Announce new release 0.9.0 of librest

I’m pleased to announce the release of 0.9.0 of librest, a library meant to interact with “Restful” web services. This library is very old and not really big but it handles the aspect of interaction with REST-APIs in a convenient fashion. After a long period of maintenance state i picked it up and brought it into 2022. Most of the deprecated API calls are gone now and it should be now possible to parallel-install librest with the previous release.

So what is this in detail and how does it work?

Basically its an abstraction of libsoup which is an HTTP client. If you would use libsoup directly it happens to create some kind of abstraction is necessary for your usecase in order to encapsulate all REST functions with their necessary HTTP calls. Here ´librest` tries to help by providing an abstraction fitting to the REST usecase in general.

Getting started

Typically a REST interface contains the host on which data need to be fetch/posted and a function.

rest01.png

librest encapsulates the host in a RestProxy. Every call to the REST interface starts from there. The creation is a simple

RestProxy *proxy = rest_proxy_new ("https://www.gitlab.com/api/v4/", FALSE);

It is possible to make the host parametrizable. For example if we want to support different API versions it is possible to do something like this:

RestProxy *proxy = rest_proxy_new ("https://www.gitlab.com/api/%s/", TRUE);

I will describe later how to fill in the void of %s in order to choose which API version we want to target.

Calling a function on the host

In order to call now a function of the host we create a new ProxyCall object.

RestProxyCall *call = rest_proxy_new_call (proxy);

Of course this object needs now some configuration in order to call the correct function we need.

rest_proxy_call_set_function (call, "version");

If you did created a parametrizable proxy you should bind the proxy before creating a new call:

rest_proxy_bind (proxy, "v4");

Ok we have now everything configured so we can execute the call:

// sync variant
GError *error = NULL;
rest_proxy_call_sync (call, &error);

// or async variant
rest_proxy_call_invoke_async (call, cancellable, my_callback_when_done, user_data);

We see its possible to call the REST interface in a blocking and in an unblocking variant (GUI tools should use the later)

Additional configuration options

By default a RestProxyCall calls the REST interface via GET in order to fetch data. Of course its possible to use other HTTP methods too via:

rest_proxy_call_set_method (call, "POST");

If you want to add query parameters or payload to your call just use the params-interface:

rest_proxy_call_add_param (call, "key", "value");

Depending on the HTTP method this will be transformed to a query or a payload.

Get resources after call

When a call is successfully you can inspect the response from the server via:

const gchar *payload = rest_proxy_call_get_payload (call);
goffset payload_length = rest_proxy_call_get_payload_length (call);

NOTE: the payload string is not null terminated as its contained in a GBytes structure. Therefore it is always recommended to use the length too. Transforming it to a null terminated string can be done via:

gchar *payload_null_terminated = g_strndup (payload, payload_length);

What about authentication?

Most REST APIs need some sort of authentication. Sadly the HTTP authentication workflow with a unauthenticated call -> respone 401 -> try basic/digest auth -> response 200 does not work because its possible to call some REST APIs also as unauthorized user.

Besides of that problem it is most often not perfect security therefore there are many more options API provider can choose. For example it is possible to secure the API with OAuth/OAuth2. Both are possible wit librest but it is necessary to use the specified Proxies for these authentication methods.

// OAuth 1.0 or 1.0a
oauth_proxy_new (consumer_key, consumer_secret, url, binding_required);

// OAuth 2
rest_oauth2_proxy_new (authurl, tokenurl, redirect, client_id, client_secret, url);

The former was already present in earlier versions of librest. I wanted to keep the namespace intact which is the reason that OAuth2 uses an prefix rest_.

Summary

I continue working on that nifty little library as i think its an important part of todays communication possibilities. I will try to reduce the code in GNOME Online Accounts because they have to maintain already the same functionality which perfectly would fit into librest.