Respect/Rest

StackOverflow: Respect/Rest uri part corresponds to controller name

Closed this issue · 3 comments

Jair C. Junior contacted me to bring his stack overflow issue under our attention. Posted today so good thing we were informed =)

Reproduced question as posted on SO:


I'm trying to implement Respect/Rest in my existing CMS.

The Problem: I would like to create a single magic route to works like: /admin/*/save, calls the * controller...

I would like to make something like this:

$r->any('/admin/*/save/*/', function($controller, $id = null) use ($r) {
  return $r->dispatchClass($controller,array($id));
});

Note that I don't know which HTTP method user is using.

Actually I "solved" this problem with something like:

$r->any('/admin/*/save/*/', function($controller, $id = null) use ($tcn) {
  $r = new Router;
  $r->any('/admin/*/save/*/', $tcn($controller . '_save'), array($id));
  return $r->run();
});

$tcn is a named function that returns the full namespace of the controller.

I know it's not a good approach.


@Respect and friends, if anyone has a moment please respond, unfortunately I am all tied up atm. We should also scan SO for any other Respect related and unattended questions again. I wonder if we could script for that...

I think it's not a good approach because i'm creating a new instance from within a route.
I tried to pass the instance like:
use ($tcn, $r /* router instance */)

But it resulted in conflicts with the catch-all rule... sometimes the catch-all rule would be called first, even when it's declared after the other (and the route matches the previous one)

Besides, there is a method called "dispatch" which should do the job, but it requires an URI. It assumes that I already have another rule to treat the URI which is not the case.

Alganet has started answering form StackOverflow. I don't know if you guys wanna close this issue or do you want me keep here updated

@jaircuevajunior tx for the heads-up again =)

@alganet responded on SO


Tricky question! That depends a lot of why are you making these routes dynamic. Can you show us some sample structure for your controllers so I can improve the answer?

Meanwhile, two native features that can help:

Forwards

You can treat the problem as an internal forward (does not make redirects). It's normally to redirect to other static routes, but you can redirect to a new one as well:

$r->any(
    '/admin/*/save/*/', 
    function ($controller, $id) use ($tcn, $r) {
        return $r->any(
            "/admin/$controller/save", 
            $tcn($controller . '_save'),
            array($id)
        );
    }
);

Factory Routes

Also, Respect\Rest implements factory routes. It is experimental but stable in tests:

$r->factoryRoute(
    'ANY',
    '/admin/*/save/*/', 
    'MyAbstractController',
    function ($method, array $params) use ($tcn) {
        return new $tcn($params[0] . '_save');
    }
);

Issue considered resolved.