wellrested/documentation/handlers.md

136 lines
5.1 KiB
Markdown

# Handlers
[`Handler`](../src/pjdietz/WellRESTed/Handler.php) is an abstract base class for you to subclass to create controllers for generating responses given requests.
## Instance Members
Your [`Handler`](../src/pjdietz/WellRESTed/Handler.php) subclass has access to three protected members:
Member | Type | Description
---------- | ---- | -----------
`args` | `array` | Map of variables to supplement the request, usually path variables.
`request` | [`RequestInterface`](../src/pjdietz/WellRESTed/Interfaces/RequestInterface.php) | The HTTP request to respond to.
`response` | [`RequestInterface`](../src/pjdietz/WellRESTed/Interfaces/ResponseInterface.php) | The HTTP response to send based on the request.
## HTTP Verbs
Most of the action takes place inside the methods called in response to specific HTTP verbs. For example, to handle a `GET` request, implement the `get` method.
```php
class CatsCollectionHandler extends \pjdietz\WellRESTed\Handler
{
protected function get()
{
// Read some cats from the database, cache, whatever.
// ...read these an array as the variable $cats.
// Set the values for the instance's response member. This is what the
// Router will eventually output to the client.
$this->response->setStatusCode(200);
$this->response->setHeader("Content-Type", "application/json");
$this->response->setBody(json_encode($cats));
}
}
```
Implement the methods that you want to support. If you don't want to support `POST`, don't implement it. The default behavior is to respond with `405 Method Not Allowed` for most verbs.
The methods available to implement are:
HTTP Verb | Method | Default behavior
--------- | --------- | ----------------------
`GET` | `get` | 405 Method Not Allowed
`HEAD` | `head` | Call `get`, then clean the response body
`POST` | `post` | 405 Method Not Allowed
`PUT` | `put` | 405 Method Not Allowed
`DELETE` | `delete` | 405 Method Not Allowed
`PATCH` | `patch` | 405 Method Not Allowed
`OPTIONS` | `options` | Add `Allow` header, if able
### `OPTIONS` requests and `Allowed` headers
An `OPTIONS` request to your endpoint should result in the API responding with an `Allow` header listing the verbs the endpoint supports. For example:
```
HTTP/1.1 200 OK
Allow: GET, HEAD, POST, OPTIONS
Content-Length: 0
```
To support `OPTIONS` requests, implement `getAllowedMethods` and return an array of the methods you support. For a handler that supports the methods in the example response, do this:
```php
protected function getAllowedMethods()
{
return array("GET", "HEAD", "POST", "OPTIONS");
}
```
You do not need to implement `options`. `options` by default calls `getAllowedMethods`. If it gets a return value, it sets the status code to `200 OK` and adds the `Allow` header. Otherwise, it responds `405 Method Not Allowed`.
### Custom Verbs
To support custom verbs, redefine the `buildResponse`. To respond to the custom verb `SNIFF`, to this:
```php
protected function buildResponse()
{
switch ($this->request->getMethod()) {
case 'SNIFF':
// Assuming you also made a sniff() method...
$this->sniff();
break;
default:
// Let the parent's method do the rest.
self::buildResponse();
}
}
```
## HttpExceptions
Another useful feature of the [`Handler`](../src/pjdietz/WellRESTed/Handler.php) class is that it catches exceptions deriving from [`HttpException`](../src/pjdietz/WellRESTed/Exceptions/HttpExceptions.php) and turns them into responses.
[`HttpException`](../src/pjdietz/WellRESTed/Exceptions/HttpExceptions.php) and its subclasses provide the status code and description for simple error responses.
For example, you can throw a `NotFountException` if the resource the request indicates does not exist.
```php
use \pjdietz\WellRESTed\Handler;
use \pjdietz\WellRESTed\Exceptions\HttpExceptions\NotFoundException;
class CatsCollectionHandler extends Handler
{
protected function get()
{
// Lookup a cat by ID.
$cat = Cat::getById($this->args["id"]);
if (!$cat) {
throw new NotFoundException();
}
$this->response->setStatusCode(200);
$this->response->setHeader("Content-Type", "application/json");
$this->response->setBody(json_encode($cat));
}
}
```
Your [`Handler`](../src/pjdietz/WellRESTed/Handler.php) will automatically turn this into a `404 Not Found` response.
Here are the available [`HttpException`](../src/pjdietz/WellRESTed/Exceptions/HttpExceptions.php) classes:
Response Code | Class
--------------------------- | -----------------------
`400 Bad Request` | `BadRequestException`
`401 Unauthorized` | `UnauthorizedException`
`403 Forbidden` | `ForbiddenException`
`404 Not Found` | `NotFoundException`
`409 Conflict` | `ConflictException`
`500 Internal Server Error` | `HttpException`
You can also create your own by subclass `HttpException` and setting the exception's `$code` to the status code and `$messge` to a default message.