This document assumes you’ve installed hiraeth/bootstrap
or a combination of hiraeth/diactoros
, hiraeth/fastroute
, and hiraeth/actions
.. If you haven’t your mileage may vary. See the installation docs for more information.
Responders take the return result of an action and convert it to a PSR-7 response object. In most cases this will be totally transparent to the user as hiraeth/bootstrap
comes with a number of common responders out of the box. However, if you’re writing an API, creating custom responders is an extremely powerful way to handle conversion of data transfer objects, models, collections, etc, to the client.
By default hiraeth/bootstrap
comes with the following responders:
Responder | Description |
---|---|
NativeResponder | Handles a returned PSR-7 Response object, makes no modifications |
JsonResponder | Handles a returned array, stdClass, or JsonSerializable, converts to JSON |
FileResponder | Handles a returned SplFileINfo object, discerns content type via extension |
StringResponder | Handles a returned string, discerns content type based on content |
TemplateResponder | Handles a returned template, discerns content type via the template extension |
Creating a Responder
Responders must implement the Hiraeth\Routing\Responder
. In order to implement this interface you will need to implement two methods.
Method | Description |
---|---|
match() |
Determine whether or not that responder should be used to convert the action’s return value |
__invoke() |
Perform the conversion of the action’s return value into a PSR-7 response object |
Both methods receive the Hiraeth\Routing\Resolver
as an argument which allows you to access the return value of the action.
As an example, let’s begin by looking at the Hiraeth\Routing\NativeResponder
.
Matching the Response
The match()
method takes the Hiraeth\Routing\Resolver
, on which you can use getResult()
to get the return value from the action. It returns TRUE
in the event it knows how to convert the result to a response, FALSE
otherwise. The first responder to return TRUE
is chosen to send the response.
The Hiraeth\Routing\NativeResponder
matches if the return value of the action is a already a PSR-7 response object.
public function match(Resolver $resolver): bool
{
return $resolver->getResult() instanceof Psr\Http\Message\ResponseInterface;
}
Converting the Response
Once a responder is matched, it will be invoked via the __invoke()
method. The __invoke()
method is responsible for taking the information from the return value and mapping it or converting it to a valid Psr\Http\Message\ResponseInterface
. In our previous example, the result was already a valid PSR-7 response object, so it would only return the original result.
Here, we’ll look at the Hiraeth\Routing\StringResolver
. In this instance, we would have matached if the return result from the action was a native PHP string
. As with the match()
method, we receive the resolver. From there, we can getResult()
and convert it:
{
$result = $resolver->getResult();
$response = $resolver->getResponse();
$stream = $this->streams->createStream($result);
$mime_type = $resolver->getType($stream);
return $response
->withBody($stream)
->withHeader('Content-Type', $mime_type)
->withHeader('Content-Length', (string) $stream->getSize())
;
}
Registering Responders
Responders can be registered by creating a new file in config/responders
, e.g. config/responders/acme.jin
with a [responder]
section and specifying the class
of the responder:
[responder]
class = Acme\Responder\CustomResponder
Responders are matched in the order of their specified priority
in the config. The first to match will be executed, so if you have a responder that handles the same type of response as another, make sure the responder with the more specific matching criteria has a lower value.
priority = 10
If you need to disable a particular conflicting responder for some reason you can set the disabled
option to true
:
disabled = true