IceHawk request handlers
This section covers how to implement request handlers for the read and the write side.
Request handler interfaces
In order to implement a request handler for the IceHawk component you need to implement one or more of the following interfaces in your request handler class. These interfaces are more or less marker interfaces, all extending the base interfaces for handling a read or a write request.
Every marker interface defines what request method(s) are allowed for the implementing request handler class. So there is no need to add a request method string or constant to every defined route.
This is the full inheritance listing of the request handler interfaces:
- HandlesRequest (empty interface, may contain declarations in future releases)
|
|- HandlesReadRequest (defines the handle() method for read request handlers)
| |
| `- HandlesHeadRequest (marks a request handler to handle a HEAD request)
| |
| `- HandlesGetRequest (marks a request handler to handle a GET and a HEAD request)
|
`- HandlesWriteRequest (defines the handle() method for write request handlers)
|
|- HandlesPostRequest (marks a request handler to handle a POST request)
|
|- HandlesPutRequest (marks a request handler to handle a PUT request)
|
|- HandlesPatchRequest (marks a request handler to handle a PATCH request)
|
`- HandlesDeleteRequest (marks a request handler to handle a DELETE request)
These marker interfaces also allow the IceHawk component to respond automatically to an OPTIONS
request, as it just needs
to check for the implemented interfaces of the request handlers the requested URI was mapped to. Note that both, read and write side, are considered before responding an OPTIONS
request.
So you can have the same URL allowing for example a GET
request on the read side and a POST
request on the write side.
You can read more about this in our auto responding section.
Read side request handlers
For the read side HTTP offers only to verbs: GET
and HEAD
.
Where the HEAD
request should be handled and responded to exactly the same as a GET
request, except that the body is omitted in the response.
For this reason we decided to let HandlesGetRequest
inherit from the HandlesHeadRequest
interface. So if your request handler implements
HandlesGetRequest
it can respond to both, GET
and HEAD
requests.
Implenenting a handler for GET
requests is pretty easy though:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesGetRequest;
use IceHawk\IceHawk\Interfaces\ProvidesReadRequestData;
final class ShowHomepageRequestHandler implements HandlesGetRequest
{
public function handle( ProvidesReadRequestData $request )
{
# Read some data and respond
}
}
As you can see the only contract for your request handler is to implement a handle method that gets passed the read request object. So the rest is up to you.
Another advantage of only implementing an interface instead of extending an abstract or base class is to have no dependencies to base logic or any other framework-tied implementation. So you can easily write own abstract/base classes, if needed, without to worry about inheritance / overwriting of framework code. We discuss a use-case for abstract classes here.
For the sake of completeness, this is how a HEAD
-only request handler is implemented:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesHeadRequest;
use IceHawk\IceHawk\Interfaces\ProvidesReadRequestData;
final class RessourceAvailableRequestHandler implements HandlesHeadRequest
{
public function handle( ProvidesReadRequestData $request )
{
# Check for ressource existence and respond
}
}
Write side request handlers
For the write side HTTP offers 4 verbs: POST
, PUT
, PATCH
and DELETE
. The most web applications use PUT
/PATCH
/DELETE
very rarely or don't use them at all.
In most cases a remote write operation is represented by a POST
request. Some webservers don't even support PUT
, PATCH
and DELETE
.
Implementing a handler for each of the request methods is equal and as easy as the previous example for a GET
request handler.
A POST
request handler:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesPostRequest;
use IceHawk\IceHawk\Interfaces\ProvidesWriteRequestData;
final class PostNewCommentRequestHandler implements HandlesPostRequest
{
public function handle( ProvidesWriteRequestData $request )
{
# Do some write actions here and respond
}
}
A PUT
request handler:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesPutRequest;
use IceHawk\IceHawk\Interfaces\ProvidesWriteRequestData;
final class AddRessourceRequestHandler implements HandlesPutRequest
{
public function handle( ProvidesWriteRequestData $request )
{
# Do some write actions here and respond
}
}
A PATCH
request handler:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesPatchRequest;
use IceHawk\IceHawk\Interfaces\ProvidesWriteRequestData;
final class UpdateProfileRequestHandler implements HandlesPatchRequest
{
public function handle( ProvidesWriteRequestData $request )
{
# Do some write actions here and respond
}
}
A DELETE
request handler:
<?php declare(strict_types=1);
namespace YourVendor\YourProject;
use IceHawk\IceHawk\Interfaces\HandlesDeleteRequest;
use IceHawk\IceHawk\Interfaces\ProvidesWriteRequestData;
final class UnsubscribeNewsletterRequestHandler implements HandlesDeleteRequest
{
public function handle( ProvidesWriteRequestData $request )
{
# Do some write actions here and respond
}
}