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

Use PHP attributes for route definitions #3185

Open
andreas-aeschlimann opened this issue Apr 13, 2022 · 6 comments
Open

Use PHP attributes for route definitions #3185

andreas-aeschlimann opened this issue Apr 13, 2022 · 6 comments
Labels

Comments

@andreas-aeschlimann
Copy link

PHP 8.0+ allows you to use attributes for classes and methods. As a long-time slim user, I thought about implementing attributes in order to define routes.

Instead of writing

$app->get("/users/", "function", $middlewares);

, we then could directly write code like this:

#[Controller(route: "/users", middlewares: [AuthenticationMiddleware::class])]
class UserController extends AbstractController {

    #[Endpoint(method: RequestMethodInterface::METHOD_GET, route: "/", middlewares: [])]
    public function get(Request $request, Response $response, array $args): Response {
        ...
    }

}

Is this something that could be implemented in Slim as a feature?

@l0gicgate
Copy link
Member

This would require the entire routing system to be redesigned. I'm not opposed to it but this needs a lot of thought and it would be for Slim 5. There is no plan to develop Slim 5 at the moment.

@andreas-aeschlimann
Copy link
Author

This would require the entire routing system to be redesigned. I'm not opposed to it but this needs a lot of thought and it would be for Slim 5. There is no plan to develop Slim 5 at the moment.

Of course, I understand – it was more or less a random idea.

I made my own implementation but I feel like this could be done in way a better way. I have not figured out how to lazy load the controllers yet, which is quite important imo. In my implementation, it needs to read/parse all controller files first in order to generate the slim routing ($app->get(), etc...).

If this issue is ever going to be of interest, let me know and I'll be happy to assist.

Thanks a lot for your contributions to Slim, it is really great!

@MikeDevresse
Copy link

MikeDevresse commented May 6, 2022

Hi, I've implemented this thing in my company, if you do this you don't have necessarily to rewrite the routing system but just parse your controllers and read the attributes and then create the routes. But doing this cost a lot of time, so I personally decided to cache this for production. Me and my company are willing to share my code if you want, I don't think it's clean enough to be merged in the framework today, but I think it is a good starting point. Here is an example of how it works:

#[Group('/my_resource')]
#[AuthenticationRequiredMiddleware]
class ApiDeclarationGroupController extends AbstractController
{
    #[Route(method: RequestMethodInterface::METHOD_POST)]
    #[JsonContentMiddleware]
    public function postResourceAction() {

    }

I tried to use as much as possible the basic components, for example the middlewares only require to have the indication that it is an attribute in order to work.
If you need you can contact me on discord upmwqn#3475

@andreas-aeschlimann
Copy link
Author

My implementation adds a class AbstractController that has a static method called register($app). This methods looks for attributes on the class that implements AbstractController. Attributes must be given to the child controller and the controller methods. The register method simply automatically adds all necessary routes to the $app provided as parameter. From the main file (where I define the Slim app) I then will call AnyController.register($app).

It looks like @MikeDevresse has chosen a very similar approach.

There are some drawbacks and I don't know if it's possible to bypass them. One drawback is that all controllers must be initially "registered" (meaning that we need to run the register method, which execute Reflection methods on all Controllers of the entire application). There is no such thing as lazy-loading those classes, which could lead to unnecessary code executions. For smaller apps with smaller request counts, the performance hit will be negligible.

When using Slim out of the box, Controllers are not initalized/read before they actually get called. That only happens, if the route matches the given expression.

What are your thoughts @MikeDevresse?

@rodrifarias
Copy link

Hello, i created a package to try solve
https://packagist.org/packages/rodrifarias/slim-route-attributes

@mbolli
Copy link

mbolli commented Mar 20, 2023

This is supported in the upcoming release of https://github.com/juliangut/slim-routing

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

No branches or pull requests

5 participants