Description
Hi, I'm facing a problem of execution order caused (I suppose) by the withId
method of custom actions.
It seems that when I use the withId
method, the system tries to resolve the value of the ID even before executing the middleware.
Below I've attach a small code for describe the problem better. The Laravel
in use is 11
and the latest version of laravel-json-api
.
The middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class AttachGuestId
{
public function handle(Request $request, Closure $next): Response
{
dd("hello world"); // <- should exit here on request
$guestId = $request->header('guest-session-id');
session()->set('guest_id', $guestId); // try to set a session variable
}
}
The API declaration:
// ...
JsonApiRoute::server('v1')
->prefix('v1')
->middleware('verified_or_guest', 'attach_guest_id') // <----The alias of the middleware here
->resources(function (ResourceRegistrar $server) {
$server->resource('carts', CartController::class)
->actions(function (ActionRegistrar $actions) {
$actions->withId()->post('confirm');
})->middleware('attach_session_id'); // <---- also I've try to place here
});
The method inside the controller:
// ...
public function confirm(Request $request, $cart): Responsable
{
GateFacade::authorize('confirm', $cart);
// Some stuff here...
$service = new CartService;
$order = $service->confirm($cart);
return new DataResponse($order);
}
The Cart model with a Global scope set
<?php
// ...
class Cart extends Model
{
protected function booted() {
static::addGlobalScope(function ($builder) {
$builder->where('guest_id', session()->get('guest_id');
});
}
}
Now, when you try to execute GET /cart/:id/confirm
the response is a 404, because it seems the global scope return no results and works before executing the middleware.

Removing the global scope declaration inside the Cart model the response is:

In this case the model was found and then the middleware was executed.
Is there any way to make sure the middleware is executing first? Thanks