A presentation at PHP South Wales Online Meetup by Steve McDougall
Building APIs using Laravel A simple approach to scale
Oi, who are you? I’m Steve McDougall (JustSteveKing) ● ● ● ● PHP User Group Organiser Conference Organiser PHP Advocate Bearded man
How do people go wrong with APIs?
We have all hit that point of no return ● ● ● 100s of Models in our app directory 100s of Models in our app/Models directory More scopes than a game of Call of Duty What if there was a better way?
Setting up domains Using a simple domain approach means you can split up your business logic easily.
How do our Models look now?
What do we add to our Builder classes?
RouteServiceProvider modification
We are used to seeing this
Here is my version
JSON:API and Middleware
JSON:API has been properly registered with the IANA. Its media type designation is application/vnd.api+json.
A simple implementation
What is that about? Here is an example: application/vnd.github.v3+json We build up our content type by: type “/” “vnd.” subtype [“+” suffix] *[“;” parameter]
Handling Routing
There are quite a few ways to handle routing in Laravel
My typical approach
Let’s handle a route
A simple and flexible Action to handle a stateless request.
A clean and simple Resource
We could be a little more advanced
Handling Traits
Traits in Laravel are really handy, they allow you to share behaviour between objects to keep your code DRY. Here is one I use quite a lot on my Models:
Observing behaviour in our API
Model Observers are powerful Model Observers in Eloquent are a powerful tool when used right. Sometimes you need to share this sort of behaviour which is why in the previous example I used a Trait - however consider the following scenario: When an author creates a new post, he want this to automatically publish this post onto social media channels.
A simple approach ● ● ● Register a PostCreated event Register Listeners for each social media you wish to publish to On each listener post through the API to the social media channel. In a small scale application this would be fine. In a larger scale this is going to cause issues.
A slightly better approach ● ● ● A Model Observer handles the created event and dispatches a post to social media Job. The post to social media job handles posting to each social media API. Alternatively the Model Observer could/should dispatch a job to handle posting to each social media API separately, meaning several Jobs are dispatched. Again, this is a step forward. Posting to 3rd party APIs should be done as a background task - so we do not delay the response returning from our API.
A more advanced approach ● ● ● Our author can select per post which channels we want to share this post on, as not all social media channels are equal. Our Model Observer will dispatch a Job for each of the selected channel. When our post has been published to each channel, we can update our Post Channel relationship with meta information such as when it was posted and even a reference ID to pull analytics from the API. Not all systems will need this fine grained analytical data - but by taking a step back in our planning we can easily see how we can refactor towards it.
An Example Job
A hat tip to TDD
Laravel and API testing Laravel has a fantastic suite of testing tools, and you should be using them. The latest release of 7.* even has some great helpers for testing with a Http Client against 3rd party APIs. If you aren’t already, start adding tests - you will thank me in the long run.
A simple test
What have we covered? ● ● ● ● ● ● ● ● ● ● Cleaner Models Cleaning up Routing Loading for an API Route Declarations, and there many forms Content Type middleware and JSON:API Actioning a Request coming into our API API Resources for consistency How useful Traits can be Mode Observers and examples of when to use them Dispatchable Jobs Testing is important, even if they are simple.
APIs do not have to be hard. But they do have to be stateless.
Thanks for listening Twitter: @JustSteveKing GitHub: JustSteveKing
A lot of people are building APIs, and a lot of people are hitting the same issues. In this presentation I go through the common issues I have seen in scaling a Laravel API, and what you can do now to improve your own.
APIs do not have to be hard. But they do have to be stateless.