How to share data across multiple api endpoints in Laravel

Kiptoo Korir
3 min readNov 11, 2021
An open laptop with a code editor opened up
Photo by Mohammad Rahmani on Unsplash

If you are developing an API built on Laravel that is intended for use in production, you might end up in a situation whereby there’s some data that ends up required across multiple endpoints. This tutorial will handle how to navigate this situation with some tools right from Laravel’s arsenal.

The code from this tutorial can be found on github on this link. Feel free to clone it to follow along.

Project setup

With the project cloned, setup the .env file with the environment variables and run composer update to install the packages needed by Laravel to work.

Once the application is setup, setup the database with the tables and the dummy data needed for the endpoints using the following commands:

php artisan migrate
php artisan db:seed

Api endpoints

The application contains two endpoints which return the activities and notifications of a user, in this case the user with id 1.

/{id}/notifications
/{id}/activities

The aim of the tutorial is to return the notification count bundled with the data on both endpoints.

Defining the middleware

To alter the response from the two endpoints, we will use Laravel’s middleware.

Middleware, as defined by the docs, are a convenient mechanism for inspecting and filtering HTTP requests going into an application. While middleware are commonly known to be used to influence an application’s behavior before the request arrives at the controller level, they can be similarly deployed to perform tasks after the request has been processed and a response is being returned.

Create a new middleware to handle the problem of sending the notification count as part of the response.

php artisan make:middleware PassNotificationCount

Create a function in the middleware class to handle the query to draw the notification count.

protected function getNotificationCount()
{
return Notification::where(['notifiable_id' => 1])->whereNull('read_at')->count();
}

Code in the handle function will handle the logic with which the notification count will be added to the response, as so:

public function handle(Request $request, Closure $next)
{
$reponse = $next($request);

$notificationCount = $this->getNotificationCount();
$responseData = $response->getData();
$responseData->notificationCount = $notificationCount;

$response->setContent(json_decode($responseData));
return $response;
}

The statement $response = $next($request) grabs the response object and stores it in the $response variable. Invoking the closure $next instructs the program to execute normally as it would have if it were not intercepted by the middleware.

In this case, it allows the code in the controller first, after which the code in the middleware will be executed.

The $response variable has a few methods available to it, getData() is one of these methods and returns the data embedded in the response as an object.

We can then add an attribute of notificationCount to the object which we have and have the value of this attribute as the value obtained from the function obtained earlier.

The data in the $response variable can be overridden using the setContent() method which expects a single parameter of type string. We therefore have to encode the object.

With that, we can return the response to the normal flow of execution.

With the logic in the middleware out of the way, we still need to register the new middleware in the Kernel.php file.

protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
...
...
...
'notificationcount' => \App\Http\Middleware\PassNotificationCount::class,
];

Once the middleware is registered, we can now add it to our routes so that whenever the endpoints are opened, the return value returns the notification count.

Route::middleware(['notificationcount'])->group(function () {
Route::get('/{id}/notifications', [NotificationsController::class, 'getNotifications'])->name('getNotifications');
Route::get('/{id}/activities', [ActivitiesController::class, 'getActivities'])->name('getActivities');
});

If you check on the two endpoints after the process, an extra attribute can be seen, containing the notification count.

Conclusion

With that, you can conveniently bind data across multiple endpoints without repeating your code.

Learn more about middleware from Laravel’s docs

And more about the methods used in the middleware here.

--

--

Kiptoo Korir

Web Developer | Information Geek | Occasional Poet - I talk about software development and life in general.