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

The mgrg command is a Golf service manager and here it will create a new application named "index" (it can be different from the directory it's in):
sudo mgrg -i -u $(whoami) 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 [<<p-out key>>]
         else-if
             @Added [<<p-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 [<<p-out key>>]
         else-if
             @Deleted, old value was [<<p-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 [<<p-out key>>]
         else-if
             @Value [<<p-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. It prevents leaks, and 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, and natively-compiled high-performance C code will do the rest. 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. You can still have the "heavy" implementation if you're short on RAM memory, but chances are you won't need it. In short, "light" is good because the best way not to pay a heavy price for a slow memory-safe system is not to have one.

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+.