Monday, October 28, 2024

Golf 76 released

  • Major enhancement: request handler source files can now be written in (sub)directories, such that the path leading to the request handler matches the request path. For instance, request handler "/session/user/new" will be implemented under directories "session", then "user", and then in file new.golf. This allows for clean and easy to organize structure of an application.
  • Fixed bug in parallel compilation, where reported file names in error messages were inaccurate.
  • Faster compilation by using soft links instead of copies where needed.
  • sub-handler statement has been renamed call-handler for better descriptiveness.
  • Added "public" and "private" clauses in begin-handler, to improve security features. "private" means that request handler cannot be called by an outside caller (formerly "sub-handler").
  • Added --public option in gg to toggle between request handlers being public or private by default (by default they are private).
  • Fixed spurious output from gg -m.
  • Better error message when trying to compile an application and it was not yet created.
  • p-path statement now must have a request path object, in order to make a more reliable construction of link URL paths, and to allow for static checking of requests, for faster design and development.
  • begin-handler statement now must start with a forward slash, which was up until now optional.

Web Services Security

The security of web services is a broad subject, but there are a few common topics that one should be well aware. They affect if your web application, or an API service, will be a success or not.

Many web services provide an interface to a database. SQL injection is a very old, but nonetheless important issue. A naive implementation of SQL execution inside your code could open the door for a malicious actor to drop your tables, insert/update/delete records etc. Be sure that your back-end software is SQL injection proof.

Wednesday, October 23, 2024

Golf 70 released

  • Enhanced compiler error message in if-true statement when conditional statement is missing or incomplete.
  • Fixed bug in p-path statement where it wouldn't work without new-line clause.
  • Fixed bug in set/get-param statements where it (rarely) may get stuck in wrong compiled code.
  • C style comment /*...*/ will cause an error at the beginning of statement only for readability and to avoid library detection issues.
  • Better error message when database config file is not found for a database.  

Monday, October 21, 2024

Web services with MariaDB

Create a directory for your project, it'll be where this example takes place. Also create Golf application "stock":
mkdir -p stock-app
cd stock-app
sudo mgrg -i -u $(whoami) stock

Start MariaDB command line interface:
sudo mysql

Create an application user, database and a stock table (with stock name and price):
create user stock_user;
create database stock_db;
grant all privileges on stock_db.* to stock_user@localhost identified by 'stock_pwd';
use stock_db
create table if not exists stock (stock_name varchar(100) primary key, stock_price bigint);

Golf wants you to describe the database: the user name and password, database name, and the rest is the default setup for MariaDB database connection. So create a file "db_stock" (which is your database configuration file, one per each you use):

Saturday, October 19, 2024

Golf 65 released

  • Added --parallel option to gg utility to enable multi-threaded compilation. Now the speed of making large application can be multiple times faster, for instance 3-5 times faster with a typical laptop.
  • Added high-performance hash for parameters (see set-param, get-param), making them comparable to C's stack variables in performance.
  • Removed input-count, input-name, input-value clauses from get-req statement as they are superfluous now.
  • set-param enhanced by making =<value> optional. This is often used when parameter name and the variable assigned to it have the same name. It makes the code reading and writing cleaner.

Thursday, October 17, 2024

Web service calling web service


A web service doesn't necessarily need to be called from "the web", meaning from the web browser or via API across the web. It can be called from another web service that's on a local network.

Typically, when called from the web, HTTPS protocol is used to ensure safety of that call. However, local networks are usually secure, meaning no one else has access to it but your own web services.

Thus, communication between local web services will be much faster if it doesn't use a secure protocol as it incurs the performance cost. Simple, fast and unburdened protocols, such as FastCGI, may be better.

FastCGI is interesting because it actually carries the same information as HTTP, so a web service can operate normally, using GET/POST/etc. request methods, passing parameters in URL, request body, environment variables etc. But at the same time, FastCGI is a fast binary protocol that doesn't incur cost of safety - and for local web-service to web-service communication, that's a good thing.

Just like HTTP, FastCGI can separate standard output from standard error, allowing both streams to be intermixed, but retrieved separately.

Overall, inter-web-service communication can be implemented with the aforementioned protocols in a way that preserves high-level HTTP functionality innate to web services, but with overall better performance.

Monday, October 14, 2024

Golf 56 released

Fixed bug with before-handler and after-handler statements, where the names of files used to implement them (.golf files) were not correctly stated in the documentation.

Sunday, October 13, 2024

What is Web Service


Web service is code that responds to a request and provides a reply over HTTP protocol. It doesn't need to work over the web, despite its name. You can run a web service locally on a server or on a local network. You can even run a web service from command line. In fact, that's an easy way to test them.

The input comes from an HTTP request - this means via URL parameters plus (optional) request body.

The parameters could be in URL's path (such as "/a=b/c=d/...") or in its query string (such as "?a=b&c=d...") or both - this data is typically limited in size to 2KB. Additional parameters could be appended to the request body - this is for instance how files are uploaded in an HTML form.  

Request body itself can be any data of any size really - web services typically have an adjustable size limit for this data just to avoid mistakenly (or maliciously) huge ones. A request body could contain for example a JSON document, or some other kind of data.

The output of web service can be HTML code, JSON, XML, an image such as JPG or just about anything really. It's up to the caller of web service to interpret it. One such caller is web browser, another one could be API from an application etc.

What's the difference between a web application and a web service? Well, technically a web application should be a collection of web services, which are typically more basic service providers. That's why web services are often used as endpoints for remote APIs. They generally have a well defined input and output and are not too big. They serve a specialized purpose most of the time.

Friday, October 11, 2024

Cache as a web service


This example shows Apache as the front-end (or "reverse proxy") for cache server - it's assumed you've completed it first. Three steps to setting up Apache quickly:
  1. Enable FastCGI proxy used to communicate with Golf services - this is one time only:

Wednesday, October 9, 2024

Cache server in 30 lines


This is a cache server that can add, delete and query key/value pairs, with their number limited only by available memory.

We'll use "tree" type, which is a high-performance data structure. For example, with 1,000,000 keys it will take only about 20 comparisons to find any key; and the range search is just one hop. Tree type is based on a modified AVL/B tree.

Create new "index" application first, in a new directory (you can name it anything you like):
mkdir -p index
cd index

Create a new application named "index" (it's name can be different from the directory it's in):
gg -k index

Create a source code file "srv.golf":
vi srv.golf

and copy and paste this:
 begin-handler /srv public
     do-once
         new-tree ind process-scope
     end-do-once
     get-param op
     get-param key
     get-param data
     if-true op equal "add"
         write-tree ind key (key) value data status st
         if-true st equal GG_ERR_EXIST
             @Key exists [<<print-out key>>]
         else-if
             @Added [<<print-out key>>]
         end-if
     else-if op equal "delete"
         delete-tree ind key (key) value val status st
         if-true st equal GG_ERR_EXIST
             @Not found [<<print-out key>>]
         else-if
             @Deleted, old value was [<<print-out val>>]
         end-if
     else-if op equal "query"
         read-tree ind equal (key) value val status st
         if-true st equal GG_ERR_EXIST
             @Not found, queried [<<print-out key>>]
         else-if
             @Value [<<print-out val>>]
         end-if
     end-if
 end-handler

A service will run as a single process because each operation is handled very fast

Tuesday, October 8, 2024

Golf 54 released

  • Improvement: Faster gg utility for services execution from command line (-r option)
  • Bug fix:  "-z" option in mgrg would have no effect in some cases, meaning the silent header would not be honored and the HTTP header would always be output, specifically if "--silent-header" is omitted in "gg -r". This now works as documented. 

Sunday, October 6, 2024

Memory safety: the cost in performance

Memory safety guards against software security risks and malfunctions by assuring data isn't written to or read from unintended areas of memory. Preventing leaks is a separate feature that's important for web services which are long-running processes - memory leaks usually lead to running out of memory and crashes.

But what of the performance cost of memory safety?  Golf is a very high level programming language. It's not like other languages, and you can intuitively experience that just by looking at the code. It feels more like speaking in English than moving bits and bytes or calling APIs.

So when you build your web services, you won't write a lot of code, rather you'd express what you want done in a declarative language. This code is designed to be memory safe, but because it's C, it avoids the penalty of being implemented in a general-purpose memory-safe language, where everything that's done, from bottom up and top down, would be subject to memory-safety checks.                                                                

As a result, the cost incurred on memory safety is mostly in checking input data of such statements and not in the actual implementation which is where most of the performance penalty would be. In addition, the output of Golf statements is generally new immutable memory, hence it needs no checking. This means memory safety checks are truly minimal, and likely close to a theoretical minimum.

Golf also has a light implementation of memory safety. One example is that any memory used in a request is by default released at the end of it, and not every time the memory's out of scope, which saves a lot of run-time checks. 

In summary, the choices made when designing and implementing a memory safe programming language profoundly affect the resulting performance.

Tuesday, October 1, 2024

Golf 50 released

 New features and improvements:

  • Added HMAC (Hash Message Authentication Code) support with hmac-string statement.
  • Updated OpenSSL-based statements handling to be able to use custom digests/ciphers available in version 3+.

Sunday, September 29, 2024

SQLite with Golf


This example will create a service that inserts key and value into SQLite table. It's tested from command line.

Create a directory and then switch to it:
mkdir sqlite
cd sqlite

Setup SQLite database in file "mydata.db":
echo 'drop table if exists key_value; 
create table if not exists key_value (key varchar(50) primary key, value varchar(100));' | sqlite3 mydata.db

Create configuration file "mydb" that describes the SQLite database "mydata.db":
echo "$(pwd)/mydata.db"> mydb

Create the application:
sudo mgrg -i -u $(whoami) sqlite

Create file insert.golf:
vim insert.golf

Copy and paste to it (note use of database configuration "mydb" in @mydb):
 %% /insert public
     get-param key
     get-param value
     run-query @mydb = "insert into key_value(key,value) values ('%s', '%s')" input key, value error err affected-rows aff_rows no-loop
     @Error <<print-out err>>, affected rows <<print-out aff_rows>>
 %%

Compile the application - we specify that file "mydb" is describing SQLite database:

Copy-code icon added

Copy icon () is now in the upper right corner of all code blocks in Golf documentation, as well as this blog.

Click this icon to copy the code. This is useful for getting the sample code in your own, learning Golf etc.

Friday, September 27, 2024

Golf 44 released

Bug fixes:
  • Fixed bug where a memory for parameters or split-string type could be allocated with no data causing invalid write in debug mode only. 
  • Fixed bug where passing a number from sub-request back to the caller would not be correct or could cause invalid memory read.
  • Fixed bug in encryption statement (encrypt-data) with checking memory bounds of Initialization Vector (IV).
  • Fixed bug in executing SQL with any database. The bug was with checking the formatting of the statement.
New features and improvements:
  • Added -z command-line option to Service Manager (mgrg). This option suppresses HTTP header  for all service requests in application (equivalent to implicit silent-header statement at the beginning of each request handler).
  • Improved performance of piping output from execution of programs in exec-program statement.
  • Improved performance of message composition in write-message statement.
  • Structured types can now be returned to caller from sub-handler - for instance creating a new index or array.

Thursday, September 26, 2024

Overview of Golf

Golf is a new programming language and framework for developing web services and web applications. The reason for Golf is to make software development easier and more reliable.

Golf is a declarative language designed for simplicity. That means top-down approach, rather than bottom-up: it's more about describing what to do than coding it. It's a modeling language where pieces are assembled together quickly and with confidence. It's about the framework to create and deploy web services based on what they need to do from human perspective, more so than the technical one.

Underlying Golf's functionality are industry-standard Open Source libraries, such as SSL, Curl, MariaDB and others, in addition to native Golf's.

In extended mode, Golf is extensible with any standard libraries. You can also include C files directly in your project to compile with it. In this mode, Golf (obviously) does not guaratee memory safety, but it does not necessarily mean it's not safe either.

Tuesday, September 24, 2024

Golf 37 released

  • Added "new-line" clause to output statements, such as p-out, p-web, p-url, p-path and p-num. This clause adds new line to the output of any of these statements.
  • Fixed bug in write-string where program errors out in some cases with multiple use of encoded output statements, such as p-web for instance.

Saturday, September 21, 2024

Web service Hello World


To access a Golf service on the web, you need to have a web server or load balancer (think Apache, Nginx, HAProxy etc.).

This assumes you have completed the Hello World as a Service, with a service built and tested via command line.

In this example, Nginx web server is used; edit its configuration file. For Ubuntu and similar:
sudo vi /etc/nginx/sites-enabled/default

while on Fedora and other systems it might be:
sudo vi /etc/nginx/nginx.conf

Add the following in the "server {}" section:
location /hello/ { include /etc/nginx/fastcgi_params; fastcgi_pass  unix:///var/lib/gg/hello/sock/sock; }

"hello" refers to your Hello World application. Finally, restart Nginx:
sudo systemctl restart nginx

Now you can call your web service, from the web. In this case it's probably a local server (127.0.0.1) if you're doing this on your own computer. The URL would be:
http://127.0.0.1/hello/hello-world/name=Mike

Note the URL request structure: first comes the application path ("/hello") followed by request path ("/hello-world") followed by URL parameters ("/name=Mike"). The result:

Hello World as a Service


Writing a service is the same as writing a command-line program in Golf. Both take the same input and produce the same output, so you can test with either one to begin with.

For that reason, create first Hello World as a command-line program.

The only thing to do afterwards is to start up Hello World as application server:
mgrg hello

Now there's a number of resident processes running, expecting clients requests. You can see those processes:
ps -ef|grep hello

The result:
bear       25772    2311  0 13:04 ?        00:00:00 mgrg hello
bear       25773   25772  0 13:04 ?        00:00:00 /var/lib/gg/bld/hello/hello.srvc
bear       25774   25772  0 13:04 ?        00:00:00 /var/lib/gg/bld/hello/hello.srvc
bear       25775   25772  0 13:04 ?        00:00:00 /var/lib/gg/bld/hello/hello.srvc
bear       25776   25772  0 13:04 ?        00:00:00 /var/lib/gg/bld/hello/hello.srvc
bear       25777   25772  0 13:04 ?        00:00:00 /var/lib/gg/bld/hello/hello.srvc

"mgrg hello" runs the Golf process manager for application "hello". A number of ".../hello.srvc" processes are server processes that will handle service request sent to application "hello".

Now, to test your service, you can send a request to the server from command line (by using "--service" option):
gg -r --req="/hello-world/name=Mike" --exec --silent-header --service

The above will make a request to one of the processes above, which will then reply:
This is Hello World from Mike

Friday, September 20, 2024

Golf 32 released

  • HTTP header is now sent to client by default at the very first output, i.e. the equivalent of 'out-header default' statement.No code change is necessary. Typical use of out-header is to send default headers at the very beginning of a service, and those can in general be removed now, since it's done automatically.

  • Color scheme is now supported for Golf source code. Prior to this release, there was one hardcoded colorscheme. Now your can use any available color  scheme to customize look and feel of source code in Vim editor (use ":colorscheme" command).

Thursday, September 19, 2024

Using Vim color schemes with Golf


Golf installation comes with a Vim module for highlighting Golf code. After installing Golf, run this to install the Vim module:
gg -m

The default color scheme looks like this:
To change color scheme, type ":colorscheme " in command mode, then press Tab to see available color schemes. Press Enter to choose one. For instance, in 'darkblue' color scheme, it may look like:
To make the change permanent, edit file ".vimrc" in home directory:
vi ~/.vimrc

and append line:
colorscheme darkblue

Tuesday, September 17, 2024

Hello World in Golf


Create a directory for your Hello World application and then switch to it:
mkdir hello-world
cd hello-world

Create the application:
sudo mgrg -i -u $(whoami) hello

Create a file hello-world.golf:
vim hello-world.golf

and copy this code to it:
 begin-handler /hello-world public
     get-param name
     @This is Hello World from <<print-out name>>
 end-handler

This service takes input parameter "name" (see get-param), and then outputs it along with a greeting message (see output-statement).

Compile the application:

Friday, September 13, 2024

Introduction to Golf


Golf is a new programming language and framework for developing web services and web applications. It is:
  • declarative language designed for simplicity,
  • memory-safe,
  • functional statically-typed,
  • high-performance compiled language, designed to create fast and small native executables without interpreters or p-code,
  • built on top of industry-standard Open Source libraries, such as SSL, Curl, MariaDB and others, in addition to native Golf's,
  • extensible with any standard libraries,
  • very simple to work with by design to reduce comlexity and improve performance.

Thursday, September 12, 2024

Initial Golf release

Version 25 is an initial Golf release.

The official web site is at golf-lang.com. It is also accessible (for now, but not indefinitely) from vely.dev since Golf evolved from Vely. Golf and Vely are copyright (c) Gliim LLC licensed under their respective licenses and developed by the same team.

The official Golf source code repository is at github.com/golf-lang/golf.

Golf is licensed under Apache 2 Free Open Source license.