Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark routes in router as JSON API routes #250

Open
MeiKatz opened this issue Jun 14, 2023 · 7 comments
Open

Mark routes in router as JSON API routes #250

MeiKatz opened this issue Jun 14, 2023 · 7 comments

Comments

@MeiKatz
Copy link

MeiKatz commented Jun 14, 2023

Currently there is no bulletproof way of filtering routes created by JSON API. But there might be a solution by adding JSON API routes as instances of a sub-class of Illuminate\Routing\Route. With this it would be easy to filter out routes from JSON API just by checking if a route is an instance of a JSON API route class or not. Or if such a route implements a contract from JSON API.

It is quite simple:

class JsonApiRoute extends Illuminate\Routing\Route {}

// get router
$router = Illuminate\Support\Facades\Route::getRoutes();
// add json api route
$router->add( new JsonApiRoute( $methods, $uri, $action ) );

// ... that's it!

Later we could filter out the json api routes like this:

$routes = Illuminate\Support\Facades\Route::getRoutes()->getRoutes();

$json_api_routes = array_filter( $routes, function ( $route ) {
  return ( $route instanceof JsonApiRoute );
});
@ben221199
Copy link

I am not fully expert in the Laravel routing at the moment, but does this also work when routes are cached with php artisan route:cache? If that is the case, I think I like this approach.

@MeiKatz
Copy link
Author

MeiKatz commented Jun 15, 2023

@ben221199 Good question. I haven't checked this yet but might do it later today. I will keep you updated!

@MeiKatz
Copy link
Author

MeiKatz commented Jun 15, 2023

Okay, did a quick check. Currently it seems like routes from Laravel JSON api are not cached at all. Therefore it seems to be a bug, because caching my routes crashes my app ...

@MeiKatz
Copy link
Author

MeiKatz commented Jun 15, 2023

This is my RouteServiceProvider (extract):

class RouteServiceProvider extends ServiceProvider {
  public function boot() {
    Route::prefix('api')
      ->middleware('api')
      ->group(function () {
        $this->getJsonApiServer()->resources(function ( ResourceRegistrar $server ) {
          $callback = require_once( base_path('routes/api/v1.php') );

          if ( $callback instanceof \Closure ) {
            $callback( $server );
          }
        });
      });
  }

  private function getJsonApiServer(): PendingServerRegistration {
    return (
      ResourceRegistrar::server('v1')
        ->prefix('v1')
        ->namespace('\\')
    );
  }
}

And my routes file (routes/api/v1.php) looks like this:

return function ( ResourceRegistrar $server ) {
  $server
    ->resource(
      'access_tokens',
      AccessTokenController::class
    )
    ->only(
      'store',
      'show',
      'destroy',
    );

  // ...
};

@MeiKatz
Copy link
Author

MeiKatz commented Jun 15, 2023

Okay, if we keep the ability to cache routes in mind, then my proposed approach will not work. But maybe it is possible to add a "tagged" "dummy middleware" and we can check the routes for the existence of this middleware. Via the "tag" we could also filter the version / server that defined a route. For example "jsonapi:v1" would tell that it is a route defined by JSON API and the "tag" would say, that it is from the server "v1".

@lindyhopchris
Copy link
Contributor

Currently it seems like routes from Laravel JSON api are not cached at all

You mean, when using this extended class? They definitely do work for the current implementation, because I use cached routes in my production apps without any problems.

I'd be intrigued to look into the Laravel route caching to see why an extended class doesn't work. Implies they're not serializing the objects directly but doing something else.

@MeiKatz
Copy link
Author

MeiKatz commented Jun 15, 2023

@lindyhopchris no, when I run php artisan route:cache there are no JSON API routes in the cached file. Not sure why, because when I run $routes->compiled() all routes are included. Seems to be a problem on its own.

Anyway, I think there is no way to get the route class from the route cache file. But middlewares are included in the cache file and this might be a solution for this package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants