How to use Restful Controller on Slim 3


#1

I registered route with Restful Controller like this:

$app->any('/user', 'UserController');

This is my codes for UserController

namespace App;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class UserController
{
    function __invoke(){
    }

    function list(ServerRequestInterface $request, ResponseInterface $response){
        return $response;
    }
}

I tried to access http://localhost/demo/user/list. But it isn’t working and return status code 404. There’re no guide for Restul Controller in document here. Help me, please.


#2

I don’t know the answer to your problem off the top of my head, but saying “it’s not working” is not very helpful. Please be specific in what type of error/issue you’re getting and it will be much easier for us to help you.


#3

Sorry, It’s return status code 404.


#4

Ok, sorry. I understand right now. I should handle $request & $response in __invoke. Thanks.


#5

Glad you were able to solve your problem. I would suggest however that you change your route definition to

$app->any('/user', 'UserController:list')->setName('list');

since this will invoke the list() method directly and not rely on the magic __invoke() method. Doing it this way also allows you to cleanly separate multiple route functions in a single class.

Note: the setName() call is not required but it’s considered good practice to do this as it allows you to later on query the route name should you need to make decision based upon which route was called.


#6

Thanks for your suggest. I want to make a parent class with __invoke() to handle $request & $response which can map method to route automatically from child class.

And then, I can simple register child class UserController for example

$app->any('/user', 'UserController')

with

getList => GET /user/list
postList => POST /user/list
getShowProfile => GET /user/show-profile

It should be good or bad idea?


#7

Quite honestly, I don’t know. My first thought is that you’re overcomplicating things, but if this approach works for you and you’re happy with it, then by all means continue using it.


#8

OK, maybe you’re right. I should take a look for another way.

Thanks so much.


#9

Here’s an excerpt from my routes.php.

$app->get  ('/faq',      'App\Controller\UserController:faq')->setName ('guest_faq');
$app->get  ('/login',    'App\Controller\UserController:login')->setName ('guest_login');
$app->get  ('/logout',   'App\Controller\UserController:logout')->setName ('guest_logout');

In my opinion (and I may not be 100% correct here) this is simple, clear and readable.

Please don’t misunderstand: I’m not trying to tell you how to write your code, I’m just trying to give the best advice I know for Slim.


#10

I’ve seen that pattern used successfully before. No reason not to do it if you want to have a single mapping in your routes list.


#11

I don’t know if it’ll be usefull for you, but if you want to know how to pass the Request, Response Objects to your own Controller Class instead of the Method, this post Here will be usefull to you.

Its tricky and not out of the box but in my case I found it usefull and as I can see you are looking for more customization and control.