Skip to content

withId executed before middlewares #310

Open
@beliven-fabrizio-gortani

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.

Image

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

Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions