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)

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.

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

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