C language API to talk to Golf server

Golf application server can be accessed via C API. Most programming languages allow for C linkage, so this makes it easy to talk to Golf server from anywhere. The Client-API is very simple with just a few functions and a single data type. It's also MT-safe (i.e. safe for multi-threaded applications). In this example, a Golf server will use a tree object to store key/value pairs, which can be added, queried and deleted for as long as the server is running (i.e. it's an in-memory database, or a cache server). Client will insert the key/value pairs, query and delete them. Create a server and start it To get started, create a directory for this example and position in it: mkdir -p c-api cd c-api Save this into a file "srv.golf": begin-handler /srv public silent-header 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 [] else-if @Added [] 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 [] else-if @Deleted, old value was [] 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 [] else-if @Value [] end-if end-if end-handler Create "index" application ("-k"): gg -k index Compile the server - this also demonstrates excluding directories from compilation (since Golf will by default try to compile the Golf and C code in all subdirectories). In this case, we're excluding subdirectory "client", which we will create in just a sec and place a C client program in it: gg -q --exclude-dir=client Start the server, with a single server process running: mgrg -w 1 index Create a client in C Create directory for a C API client, and switch to it: mkdir client cd client Next is the C code for your client. It simply inserts key/value pair, queries it, and then deletes it. Nice little program as a way of demonstration. Create file "cli.c" and copy this to it: #include "gcli.h" int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params); // Send request to Golf server and receive reply int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params) { memset ((char*)req, 0, sizeof(gg_cli)); req->server = connection; req->req_method = method; req->app_path = app_path; req->req = request; req->url_params = url_params; return gg_cli_request (req); } void main () { int res; char *urlreq, *data; gg_cli req; urlreq = "/op=add/key=some_key/data=some_data"; // Add data res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq); if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", gg_cli_data(&req)); gg_cli_delete(&req); urlreq = "/op=query/key=some_key"; // Query data res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq); if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", data = gg_cli_data(&req)); gg_cli_delete(&req); urlreq = "/op=delete/key=some_key"; // Delete data res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq); if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", data=gg_cli_data(&req)); gg_cli_delete(&req); } Compile C program: gcc -o cli cli.c $(gg -i) Run your C client ./cli The result is: Added [some_key] Value [some_data] Deleted, old value was [some_data]

Feb 13, 2025 - 02:38
 0
C language API to talk to Golf server

Golf application server can be accessed via C API. Most programming languages allow for C linkage, so this makes it easy to talk to Golf server from anywhere. The Client-API is very simple with just a few functions and a single data type. It's also MT-safe (i.e. safe for multi-threaded applications).

In this example, a Golf server will use a tree object to store key/value pairs, which can be added, queried and deleted for as long as the server is running (i.e. it's an in-memory database, or a cache server). Client will insert the key/value pairs, query and delete them.

Create a server and start it

To get started, create a directory for this example and position in it:

mkdir -p c-api
cd c-api

Save this into a file "srv.golf":

begin-handler /srv public
    silent-header
    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 [<>]
        else-if
            @Added [<>]
        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 [<>]
        else-if
            @Deleted, old value was [<>]
        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 [<>]
        else-if
            @Value [<>]
        end-if
    end-if
end-handler

Create "index" application ("-k"):

gg -k index

Compile the server - this also demonstrates excluding directories from compilation (since Golf will by default try to compile the Golf and C code in all subdirectories). In this case, we're excluding subdirectory "client", which we will create in just a sec and place a C client program in it:

gg -q --exclude-dir=client

Start the server, with a single server process running:

mgrg -w 1 index

Create a client in C

Create directory for a C API client, and switch to it:

mkdir client
cd client

Next is the C code for your client. It simply inserts key/value pair, queries it, and then deletes it. Nice little program as a way of demonstration. Create file "cli.c" and copy this to it:

#include "gcli.h"

int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params);

// Send request to Golf server and receive reply
int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params)
{
    memset ((char*)req, 0, sizeof(gg_cli));
    req->server = connection;
    req->req_method = method;
    req->app_path = app_path;
    req->req = request;
    req->url_params = url_params;
    return gg_cli_request (req);
}

void main ()
{
    int res;
    char *urlreq, *data;
    gg_cli req;

    urlreq = "/op=add/key=some_key/data=some_data"; // Add data
    res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq);
    if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", gg_cli_data(&req));
    gg_cli_delete(&req);

    urlreq = "/op=query/key=some_key"; // Query data
    res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq);
    if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", data = gg_cli_data(&req));
    gg_cli_delete(&req);

    urlreq = "/op=delete/key=some_key"; // Delete data
    res = golf_client (&req, "/var/lib/gg/index/sock/sock", "GET", "/index", "/srv", urlreq);
    if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", data=gg_cli_data(&req));
    gg_cli_delete(&req);
}

Compile C program:

gcc -o cli cli.c $(gg -i)

Run your C client

./cli

The result is:

Added [some_key]
Value [some_data]
Deleted, old value was [some_data]