Response NS
B3B8 opened this issue · 3 comments
Hi Mika
I'm working with Slim3 and in your example I see an interesting model of design pattern to handle Response PSR-7 as a separated NS (ie /src/response/NotFoundResponse.php). In API apps a lot of controllers run same function with the same response (ie Item, Collection, bad validation, db errors etc.. - Don't Repeat Yourself) and I want to use a global class/trait to handle responses from controllers and I found something in this API skeleton. But I don't understand how to handle Response $response outsite controller. Is it the right way ?
Finally, in your Response NS, all __construct call parent with
$headers = (new Headers)->set("Content-type", "application/problem+json");
but the Http Headers is null; I try to separate it like this
$headers = new Headers();
$headers->set("Content-type", "application/problem+json");
and Http Headers are set correctly. It's a mistake ?
Thank you so much!
You are correct it is a bug. It seems I have assumed Headers object is immutable. Thanks for the heads up!
Mika can I ask you a tip to reduce the serialize lines and respective response ie
$app->post("/todos", function ($request, $response, $arguments) {
[...]
/* Serialize the response data. */
$fractal = new Manager();
$fractal->setSerializer(new DataArraySerializer);
$resource = new Collection($todos, new TodoTransformer);
$data = $fractal->createData($resource)->toArray();
return $response->withStatus(200)
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
$app->get("/todos/{uid}", function ($request, $response, $arguments) {
[...]
/* Serialize the response data. */
$fractal = new Manager();
$fractal->setSerializer(new DataArraySerializer);
$resource = new Item($todo, new TodoTransformer);
$data = $fractal->createData($resource)->toArray();
return $response->withStatus(200)
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
Start from todos routes methods, compliting my others API routes like todos with the same functions, I'll write the same serialize with the same response, so I think about "don't repeat yourself" principle and maybe with SLIM design pattern I can improve the code...Is it right use this schema or I'm just complicating myself? If it's worth, how can you rewrite it?
Thanks for your suggestion!
You could extract serializing part to external facade class and it would save a couple of lines in the route. Calling the facade could look something like.
$data = (new SerializerFacade($todo, TodoTransformer::class))->toArray()
Downside is this would make code a bit harder to follow since you have to go see the source of the facade class to understand what is happening. It is always a fine line between optimising and readability.