Request/response customization

Hi!

I’m pretty new in slim framework and after working years with “company-made” products that doesn’t really follow norms and standards, i am a little bit lost trying to do something :

I’m looking for a way to implement new request (ServerRequestInterface) and responses (ResponseInterface) objects, just to add some custom codes, for example :
a $request->trygetparam or trypostparam that would check if there is a param for a key given, and if not maybe throw an error.
a “return $response->setJsonPayload($array)” that would do the work to json encode the array, put the header on the response and so on.

I know how i could do all of that with like a class with static function that would manipulate the request/response objects but i would really like to make the elements available on the objects themselves. Having my api class be like :

public function details(MyCustomRequest $request, MyCustomReponse $response){
 $id = null;
  if($request->tryGetParam("", $id)){
    return   $response->setJsonPayload(["id"=>$id]);
  }
 return $response->error(403, "missing param");
}

I hope i’m not asking too much (or too stupid).
Thanks in advance.

Welcome @captainatwork

First you should note that Slim uses the PSR-7 standard for HTTP request and response objects. This means they are “immutable”. So every change the request/response headers must return a new (cloned) object. Second, my concern is that your approach does not comply with the PSR-7 standard and would make it later much harder to maintain.

If you are still sure to implement such an approach, you may take a look at the slim/http project on Github. This package provides some decorators for the HTTP request and response objects.

as someone that went the “custom” request / response route. (and had a fight with odan :stuck_out_tongue: ) i can safely say… dont bother with custom request / response. it WILL make your life harder (ive gone back to “mostly” vanilla slim as it really really just works)

what i now use instead is a middleware that sets up the “parameters” onto the normal $request->getAttribute()

// TODO: sanitize the inputs
        foreach ((array)$request->getQueryParams() as $key => $value) {
            $request = $request->withAttribute("GET." . $key, $value);
        }
        foreach ((array)$request->getParsedBody() as $key => $value) {
            $request = $request->withAttribute("POST." . $key, $value);
        }

        foreach ((array)$route->getArguments() as $key => $value) {
            $request = $request->withAttribute("PARAM." . $key, $value);
        }

then usage in the controller is simply $request->getAttribute("POST.name");

also this might be of some use to you as well

as for the response…

go with something like

use System\Responders\Responder;
class JobsController {
    function __construct(
        protected Responder $responder,
    ) { }

    public function __invoke(Request $request, Response $response): Response {

    	// ...

    	return $this->responder->withResponse(
            response: $response,
            data: $data,
            errors: $errors,
        );
    }
}

this lets you use your container (php-di?) in the responder as well. gives you a TON of extra options for a few bits of extra boiler plate. but it makes it super easy to switch our responders then

slim middleware is super super super strong.

thanks both of you for your answers. @odan was on point with slim/http which was basically what i was looking for, without need for me to implement a new one.

i understand that i may lose a little bit of PSR-compatibility but for the sake of simplicity for my team and myself i think it’s a fair trade to have a little bit of easy-to-use decorators (especially because, the way i managed to use it, it’s really localized to specific controllers, and doesn’t damage the framework itself). so i went with it and it worked really well.

but anyway, thanks again, and thanks to slimPHP for existing, it’s by far the simplest, and (for lack of a better term) “cutest” framework out there.