Skip to content
Insights

Saloon - Package / SDK API integrations

API integrations for a range of services, we've all been there. Multiple folders that all do exactly or almost exactly the same thing, minor differences and code that we copy/paste to keep something or other of a common thread. A problem that unfortunately happens too often.

 


To address this problem we have set up a small POC with Saloon that can start bundling all our API integrations and keep them easily reusable / maintainable via a central SDK / package.

 

What is Saloon?

Saloon provides a fluid, object-oriented wrapper to build your next API integration or PHP SDK. It makes sharing API requests in your application a breeze. You don't need to configure an HTTP client, so you can start sending requests very quickly.

If you need request faking for your tests, Saloon has this out of the box among many other useful tools such as OAuth2 boilerplate and caching. If you use Laravel, there is also a special Laravel package with artisan console commands to help you get to good results even faster.


Translated with www.DeepL.com/Translator (free version)

Demo image sallon code

SDK Tourism Flanders

As a proof of concept, we took the API of Tourism Flanders. This API has 400+ publicly accessible endpoints where you have different types of data such as: Flemish Lodges, City Tours, ...

The API that will be talked about in this example is the API of Flemish City Lodgings.

Saloon has their own template that they provide for SDKs. Here they provide the necessary examples so we can start from a clear boilerplate.

When we take a closer look at this template, we see that it includes all kinds of features such as:

  • Auth
  • Data
  • Exceptions
  • Requests
  • Collections
  • Responses

What we are going to do in the POC is to write a wrapper that has the ability to use query parameters to retrieve the Flemish lodgings filtered by city or from all cities of Flanders.

File structuur saloon template

Step 1 - Personalize the template

The template is provided with a configure PHP script which allows us to rename our template to our purpose. This script will once you have gone through all the steps of the script rename all the necessary files to your set name so no more manual import / configuration work will be needed. It will also go through the composer install and remaining installations!


In your root directory run this command:

1
php configure.php

 

Console configuratie template Saloon

Step 2 - Setup of the SDK

We'll start at the DemoSaloonSdk.php file. This is the central file of your SDK. Here the basic parameters like the base_url are filled in. This will also serve as the connector for your requests which will have to do with the Tourism Flanders API.

The first thing to do is use the trait/plugin AcceptsJson. This is a plugin provided by Saloon which ensures that you always send a JSON header on this connector.

After this, we fill in our baseUrl. In this case it is


https://opendata.visitflanders.org

 

If we look a little further we see that there is a $requests array. What we can do here is define our collections so that we can call them afterwards via a magic method and execute our request.

We will call our magic method lodgings and hang the LodgingsCollection on it as follows:

1
2
3
4
5
6
7
8
9
    /**
     * The requests/services on the DemoSaloonSdk.
     *
     * @var array
     * @method LodgingsCollection lodgings
     */
    protected array $requests = [
        'lodgings' => LodgingsCollection::class,
    ];

Everything else in the file is actually configured by default. Should you want to add a defaultConfig or defaultHeaders you can do so at the bottom of the file.

Step 3 - Collections

Now that our connector is set up, we need to create the collection we entered in $requests. Since that there is only 1 endpoint on the lodgings API we choose to create a function all() in the file. Because this is going to retrieve everything from the API.

If you go into the Requests folder you will see that there is an ExampleCollection.php present. We rename it to LodgingsCollection.php.

If we then create the agreed all() function and send the necessary query parameters to it so we can use it in the request then we can start building the request.

1
2
3
4
5
6
7
8
9
10
11
 /**
     * @throws ReflectionException
     * @throws GuzzleException
     * @throws SaloonException
     */

    public function all(?string $city = null, int $limit = -1, int $page = -1) : array
    {
        $request = $this->connector->request(new GetLodgingsRequest($city, $limit, $page));
        return $request->send()->json();
    }

 

Step 4 - Request

First of all, we rename the Example folder in Requests to Lodgings. In Lodgings, we also suddenly rename the request that we are going to use to GetLodgingsRequest.php.

In the request file we are going to build the entire request. Think of it a bit like building the body.

In our construct we pass in the necessary values that we passed in the collection:

1
2
3
4
5
6
7
8
9
10
11
12
13
    /**
     * Define constructor.
     *
     * @param string|null $city City you'd like to request lodgings from, leaving it empty will return all lodgings from Flanders.
     * @param int $limit Amount per page in pagination. -1 is the default (unlimited).
     * @param int $page current page in pagination. -1 is the default (disable pagination).
     */
    public function __construct(protected ?string $city, protected int $limit, protected int $page)
    {
        $this->city = $city;
        $this->limit = $limit;
        $this->page = $page;
    }

We define our endpoint:


/sector/accommodation/base_registry.json

We also add our query parameters:

1
2
3
4
5
6
7
8
public function defaultQuery(): array
    {
        return [
            'city' => $this->city,
            'limit' => $this->limit,
            'page' => $this->page
        ];
    }

and then we are done with the request!

Now we have a basic collection in which we can call a request in our Laravel/PHP application.

How to use it in Laravel

If we install our package on a test project we will be able to call our request as follows:

1
2
3
4
5
6
7
8
9
        $toerismeVlaanderenSdk = new DemoSaloonSdk();
        /* Specifically for Antwerp without pagination */
        $lodgings = $toerismeVlaanderenSdk->lodgings()->all('Antwerpen');

        /* All lodgings in Antwerp, per 10 paginated on page 1*/
        $lodgings = $toerismeVlaanderenSdk->lodgings()->all('Antwerpen', 10, 1);

        /* All lodgings in Flanders*/
        $lodgings = $toerismeVlaanderenSdk->lodgings()->all();

 

Conclusion

Now you can see that you can pack an API in a relatively quick way that you might be able to use in upcoming projects! Saloon opens up a lot of possibilities for both open-source and closed-source and thus can effectively make the DX a lot more enjoyable and increase work speed a lot afterwards.

Source code?

Bekijk het demo project

More insights

  • SymfonyCon 2024: code in harmony

    The 2024 edition took place in beautiful Vienna, so one of our experts went to check it out. A quick night train journey and some culture later, they were ready to focus on two days packed with Symfony. What insights did we bring back as souvenirs? You can read all about it in this report! 

    SymfonyCon 2024: code in harmony
  • Stepping into something new: Lore’s journey at Codana

    Lore Vanderlinden tells you all about her journey at Codana. She combines her technical background as a frontend developer with a passion for entrepreneurship in her role as project manager. Find out how by reading the blog!

    Stepping into something new: Lore’s journey at Codana
  • Qodo: an AI-copiloot for coding and testing

    We recently came across Qodo: a tool that uses Artificial Intelligence (AI) to help us code and test. In this blog post, you can read all about our initial experiences. 

    Qodo: an AI-copiloot for coding and testing
  • Lunar and Codana merge into one brand

    Lunar and Codana join hands and from today will continue together under the Codana brand name. This merger creates a digital product studio with more than 30 experts and a clear ambition: to become a leading player in the Belgian and European market.

    Lunar and Codana merge into one brand
  • From Intern to Digital Project Manager: My Journey at Codana

    Jelmer Krux tells you all about his journey at Codana. He joined our team fresh out of university and combines the roles of digital project manager and UX/UI Designer. How? Find out by reading his story in this blog! 

    From Intern to Digital Project Manager: My Journey at Codana
  • Cross-platform applicaties with React Native

    Never before has developing native mobile applications been as accessible as it is today. At Codana, we do this by using the React Native, an open-source framework developed by Meta.

    Cross-platform applicaties with React Native