Exploring our new PHP SDK, built using Saloon
Extracto
Today, we've launching a new PHP SDK package, which has been rebuilt from scratch using the wonderful Saloon library. Using our new SDK, you can easily use the entire Oh Dear API.
Resumen
Resumen Principal
Oh Dear ha lanzado un nuevo SDK PHP completamente reconstruido desde cero, utilizando la biblioteca Saloon, con el objetivo de simplificar y mejorar la interacción con su API. Este SDK permite a los desarrolladores integrar fácilmente las funcionalidades de Oh Dear, como la creación y gestión de monitores o la detección de enlaces rotos, a través de una interfaz moderna y eficiente. Una característica destacada es su manejo transparente de la paginación, donde los métodos que devuelven múltiples resultados operan mediante iteradores, obteniendo automáticamente páginas adicionales de la API sin requerir lógica de paginación manual por parte del desarrollador. La adopción de Saloon como base no solo agiliza el desarrollo del SDK, sino que también ofrece una estructura robusta y flexible para manejar las solicitudes y respuestas de la API, mejorando significativamente la experiencia del usuario final al trabajar con los servicios de monitoreo de Oh Dear.
Elementos Clave
- Nuevo SDK PHP Basado en Saloon: El SDK ha sido completamente reescrito utilizando la biblioteca Saloon, lo que le confiere una arquitectura moderna y eficiente. Los desarrolladores pueden instalarlo fácilmente (
composer require ohdearapp/ohdear-php-sdk
) e interactuar con la API mediante la claseOhDear
, que requiere un token de API para su inicialización. - Paginación Automática y Transparente: Una de las funcionalidades más valiosas es su manejo automático de la paginación. Métodos como
brokenLinks
no devuelven un array tradicional, sino un iterator. Al recorrer este iterador, el SDK recupera automáticamente páginas adicionales de resultados de la API en segundo plano, simplificando enormemente el manejo de grandes volúmenes de datos para el desarrollador. - Arquitectura Interna (Connector, Request, DTO): El SDK se construye sobre la estructura de Saloon, que incluye un Connector (
OhDear
class) para la configuración base (URL, autenticación, cabeceras) y clases Request específicas para cada tipo de llamada a la API (e.g.,GetMonitorRequest
), definiendo el endpoint y los parámetros. Además, emplea DTOs (Data Transfer Objects) comoMonitor
para transformar las respuestas JSON de la API en objetos PHP fuertemente tipados, facilitando el manejo de los datos. - Uso Flexible y Extensible: Aunque ofrece métodos convenientes en la clase principal para un uso sencillo (e.g.,
$ohDear->createMonitor
), el SDK también permite un control más granular. Los usuarios pueden interactuar directamente con el Connector y las Request para personalizar las llamadas a la API, aprovechando características avanzadas de Saloon como la concurrencia, lo que proporciona una gran flexibilidad.
Análisis e Implicaciones
Este lanzamiento implica una mejora sustancial en la productividad para los desarrolladores de PHP que utilizan Oh Dear, al ofrecer una integración de API más limpia y potente. La automatización de la paginación y la robusta estructura de Saloon reducen la complejidad del código, permitiendo a los equipos enfocarse en la lógica de negocio en lugar de la infraestructura de la API. Esto consolida a Oh Dear como una solución de monitoreo más accesible y amigable para el ecosistema PHP.
Contexto Adicional
El nuevo SDK PHP complementa las capacidades de monitoreo existentes de Oh Dear, que incluyen ya monitoreo de Ping y TCP. Esta expansión del tooling facilita la gestión programática de todos los aspectos del monitoreo de sitios web y aplicaciones.
Contenido
Today, next to Ping and TCP monitoring, we've also launched a new PHP SDK package, which has been rebuilt from scratch using the wonderful Saloon library. Using our new SDK, you can easily use the entire Oh Dear API.
In this blog post, I'd like to show you how you can use the new SDK and how it works under the hood.
Using the SDK
With the SDK package installed (you'll only have to require it using composer require ohdearapp/ohdear-php-sdk
), you'll be able to instantiate the Oh Dear class like this:
use OhDear\PhpSdk\OhDear; $ohDear = new OhDear('your-api-token');
That API token can be created on the API tokens screen.
On that OhDear
class you can use one of the many available API methods.
Here's how you would create a simple monitor.
$monitor = $ohDear->createMonitor([ 'url' => 'https://example.com', 'type' => 'http', 'team_id' => 1, ]); echo $monitor->url;
Of course, we'll start performing all of our checks on a new monitor right away.
Here's how you would list all broken links we detect on a site.
$brokenLinks = $ohDear->brokenLinks($monitorId); foreach ($brokenLinks as $brokenLink) { echo "Broken link: {$brokenLink->crawledUrl}"; echo "Status: {$brokenLink->statusCode}"; echo "Found on: {$brokenLink->foundOnUrl}"; echo "Link text: {$brokenLink->linkText}"; echo "Internal link: " . ($brokenLink->internal ? 'Yes' : 'No') . ""; }
Here's a cool tidbit, you can't know from looking at the code above: you don't need to care about pagination. The brokenLinks
method (and all other methods in our SDK that return multiple results) doesn't return a regular array. Instead it returns an iterator.
When you loop over the iterator, we will automatically fetch more pages of results from our API. It's completely transparent. So no matter how many broken links we detect on your site, looping over the iterator returned by brokenLinks
will handle them all.
Built on top of Saloon
This way of handling pagination (with an iterator) is powered by Saloon, which is a wonderful package to build modern PHP SDKs. I really had a fun time developing our SDK because Saloon streamlines everything so well.
At the heart of a Saloon powered SDK is Connector
. This is the class that has all of the basic information of how to connect to an API. Here's the OhDear
connector from our package (redacted for brevity).
<?php namespace OhDear\PhpSdk; use Saloon\Http\Connector; use Saloon\Http\Request; use Saloon\Http\Response; use Throwable; class OhDear extends Connector implements HasPagination { use AcceptsJson; use AlwaysThrowOnErrors; protected string $apiToken; protected string $baseUrl; protected int $timeoutInSeconds; public function __construct( string $apiToken, string $baseUrl = 'https: int $timeoutInSeconds = 10, ) { $this->apiToken = $apiToken; $this->baseUrl = rtrim($baseUrl, '/'); $this->timeoutInSeconds = $timeoutInSeconds; } public function resolveBaseUrl(): string { return $this->baseUrl; } protected function defaultAuth(): TokenAuthenticator { return new TokenAuthenticator($this->apiToken); } protected function defaultHeaders(): array { return [ 'Accept' => 'application/json', 'Content-Type' => 'application/json', ]; } protected function defaultConfig(): array { return [ 'timeout' => $this->timeoutInSeconds, ]; } }
For each different API request, you can create a class that extends Saloon\Http\Request
. In the class, you can define the URL that should be called, and the parameters it needs. Here's the GetMonitorRequest
that is used to retrieve a single monitor.
<?php namespace OhDear\PhpSdk\Requests\Monitors; use OhDear\PhpSdk\Dto\Monitor; use Saloon\Enums\Method; use Saloon\Http\Request; use Saloon\Http\Response; class GetMonitorRequest extends Request { protected Method $method = Method::GET; public function __construct( protected int $monitorId ) {} public function resolveEndpoint(): string { return "/monitors/{$this->monitorId}"; } public function createDtoFromResponse(Response $response): Monitor { return Monitor::fromResponse($response->json()); } }
That Monitor
object is a DTO class that will transform the array response from our API to a real PHP object, which is nicer to handle.
<?php namespace OhDear\PhpSdk\Dto; class Monitor { public function __construct( public int $id, public ?int $teamId, public string $url, ) {} public static function fromResponse(array $data): self { return new self( id: $data['id'], teamId: $data['team_id'], url: $data['url'], ); } }
Using the connector and the request, you can get results from the API like this.
use OhDear\PhpSdk\Requests\Monitors\GetMonitorsRequest; $request = new GetMonitorsRequest(); $response = $ohDear->send($request); $monitor = $response->dto();
By using the connector/request this way, you have full control to customize requests as you see fit (you could for example use Saloon's concurrency functionality this way.)
Now, to make it easier for the package user, I've added methods to the connector class, that wrap up those requests, so it becomes easier to use.
public function monitor(int $monitorId): Monitor { $request = new GetMonitorRequest($monitorId); return $this->send($request)->dto(); }
With this in place, users can just get a monitor like this.
$monitor = $ohDear->monitor(1); echo $monitor->url;
Easy peasy!
One thing that I'd like to highlight about Saloon, is its amazing testing facilities. Using the fixture recorder, you can easily test endpoints of the real SDK.
Here is the test of that endpoint to get a single monitor.
it('can get a single monitor', function () { MockClient::global([ GetMonitorRequest::class => MockResponse::fixture('monitor'), ]); $monitor = $this->ohDear->monitor(82063); expect($monitor->url)->toBe('https://laravel.com'); });
In the code above you can see that we use Saloon's MockResponse::fixture
function. This works a bit like snapshot testing. The first time you run this test, it will call the actual API and store its response in a file in the Fixtures
directory of the test suite. The second time this test is run, it will not call the actual API anymore, but use the response saved in the Fixtures
directory. And of course, this is a much faster test.
Notice that the test above mentioned the actual id of the created monitor. I don't mind that, because this is from our staging environment, which will be cleaned up by the time you read this. If you have sensitive values returned by your API, Saloon has got your back too as it can redact fixtures.
In closing
When I decided to rebuild our SDK in a modern way, I dreaded it a bit, as it's always a bit of tedious work. But because of Saloon, I really enjoyed the process. After creating the base setup and a couple of requests, I also used AI to complete most of the endpoints. Because Saloon divides all concerns of an SDK so nicely, the AI didn't have any problems discovering the structure. Be sure to check out the source code our package, to learn more about Saloon can be used.
As a user of Oh Dear, I hope you'll enjoy using our new SDK. All the most important API methods are covered by our SDK. Missing a method? Feel free to open a PR, or just reach out to support and we'll add it!