Generating client libraries for Recombee recommendation API

Client libraries help programmers to integrate an API into their systems in a faster, easier and more readable way. We have recently published clients for Ruby and PHP, and we wish to provide clients for other major programming languages in the near future. More supported languages means more satisfied developers, but also more maintenance — for example if you add new endpoint to the API you have to manually add corresponding methods/classes to all the clients.

This approach is prone to errors and it’s definitely not an elegant solution. Therefore we decided to generate the clients programmatically from the Open API specification of our API.

The specification describes every endpoint of the API along with taken parameters and other information. For example (a bit simplified) description of an endpoint for adding an item (product) to the database looks like this:

/items/{itemId}:
put:
summary: Add item
description: Adds new item of given `itemId` to the items catalog.
parameters:
- name: itemId
in: path
description: ID of the item to be created.
required: true
type: string

We developed a custom generator as the default swagger-codegen didn’t meet our needs. The generator transforms each endpoint to a class which takes the parameters of the request as the parameters of the constructor.

/**
* Construct the request
* @param string $item_id ID of the item to be created.
*/
public function __construct($item_id) {
$this->item_id = $item_id;
$this->timeout = 1000;
}

The instance corresponding to a request is then easily sent to Recombee with method send of the client. For example creating the client and adding an item is really simple in Ruby:

client = RecombeeClient.new('accountId', 'secret_token')
client.send(AddItem.new('IdOfTheNewItem'))

And so is in PHP:

$client = new Client('accountId', 'secret_token');
$client->send(new AddItem('IdOfTheNewItem'));

The reason why we decided to model the requests as separate classes instead of methods of the client is that this approach allows simple creating of fast batch requests. An example might be sending a batch containing addition of 100 users in Ruby:

batch = Batch.new( (1..100).map { |i| new AddUser("user-#{i}") } )
client.send(batch)

Beside the clients, we generate also the online documentation of the endpoints from the specification. This approach guarantees that the API, clients and the documentation will always stay synced.

Ruby Client — PHP Client — Documentation — Website

Do you want to try the system with one of the clients? Get access token by requesting free trial option at our website and boost your business now.

Like what you read? Give Ondra Fiedler a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.