cloudcreativity/laravel-json-api

How to attach a middleware to a specific resource relationship?

swichers opened this issue · 3 comments

Given something like:

$api->resource('foo')
  ->relationships(static function (RelationshipsRegistration $relations) {
    $relations->hasOne('bar');
    $relations->hasOne('fizz');
    $relations->hasMany('buzz');
  })
  ->middleware('example');

How can I specify a middleware for the buzz relationship independent of bar and fizz (and the main resource)? Something akin to this is what I'm looking to do:

$api->resource('foo')
  ->relationships(static function (RelationshipsRegistration $relations) {
    $relations->hasOne('bar');
    $relations->hasOne('fizz')->middleware('cache.headers:public;max_age=604800');
    $relations->hasMany('buzz');
  })
  ->middleware('cache.headers:public;max_age=600');

On that same topic, is there a way to setup different middleware per resource endpoint? I'd like to be able to target the index separately from the individual item. I have a workaround where I split out the resource into multiple definitions using ->only('index') but it seems clunky.

Hi! different middleware per resource endpoint - e.g. targeting index - I would use controller middleware.

It's been a while since I've done anything in this package as I moved development to the new package. If you can't do:

$relations->hasOne('foo')->middleware('bar');

Then your best bet is to use a Laravel route group around the relation, i.e.:

Route::middleware('foo')->group(function () use ($relations) {
    $relations->hasOne('bar');
});

That'll work. Realise it's not pretty though but it will solve your problem.

I've moved all development to the new laravel-json-api/laravel package. So if you want relationship middleware working in this legacy package, you'd need to submit a PR.

The first example doesn't work. RelationshipsRegistration (and the hasOne/hasMany methods) don't have all of the same functionality as the routes themselves.

For your second example, are you suggesting that this might work to add example to fizz?

$api->resource('foo')
  ->relationships(static function (RelationshipsRegistration $relations) {
    $relations->hasOne('bar');
    $relations->hasMany('buzz');

    Route::middleware('example')
      ->group(function () use ($relations) {
         $relations->hasOne('fizz');
       });
  });

That also does not work, though I may have misunderstood what you were suggesting. I'm not sure how bar would associate as a relationship to a resource outside of the above.

I understand this version of the library is deprecated, but the new version is a new architecture with different dependencies. That makes switching problematic.

Yeah I get upgrading isn't straight-forward, which is why I still consider this package supported for bug fixes and new versions of Laravel. However, as you can appreciate I only have limited time for open source work, so it makes sense for me to focus that on the newer version.

Exceptionally surprised that the second example doesn't work. Not sure why that would be, as wrapping route groups should work.

I'd be fine with a middleware method being added to get this working. Are you able to do a PR? If not, you'd have to wait for me to have time - and I can provide no guarantees as to when that will be.