Remove documentation and point links in README to wiki
This commit is contained in:
parent
75088499b8
commit
4a6f678bd3
|
|
@ -10,7 +10,7 @@ Version 2
|
||||||
|
|
||||||
It's more RESTed than ever!
|
It's more RESTed than ever!
|
||||||
|
|
||||||
Version 2 brings a lot improvements over 1.x, but it is **not backwards compatible**. See [Changes from Version 1](documentation/changes-from-version-1.md) if you are migrating from a previous 1.x version of WellRESTed.
|
Version 2 brings a lot improvements over 1.x, but it is **not backwards compatible**. See [Changes from Version 1](wiki/cChanges-from-Version-1) if you are migrating from a previous 1.x version of WellRESTed.
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
@ -60,7 +60,7 @@ $myRouter->addRoutes(array(
|
||||||
$myRouter->respond();
|
$myRouter->respond();
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Routes](documentation/routes.md) to learn about the various route classes.
|
See [Routes](wiki/Routes) to learn about the various route classes.
|
||||||
|
|
||||||
|
|
||||||
### Building Routes with JSON
|
### Building Routes with JSON
|
||||||
|
|
@ -134,8 +134,8 @@ class CatsCollectionHandler extends \pjdietz\WellRESTed\Handler
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Handlers](documentation/handlers.md) to learn about the subclassing the [`Handler`](src/pjdietz/WellRESTed/Handler.php) class.
|
See [Handlers](wiki/Handlers) to learn about the subclassing the [`Handler`](src/pjdietz/WellRESTed/Handler.php) class.
|
||||||
See [HandlerInteface](documentation/handler-interface.md) to learn about more ways build completely custom classes.
|
See [HandlerInteface](wiki/HandlerInterface) to learn about more ways build completely custom classes.
|
||||||
|
|
||||||
### Responses
|
### Responses
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
# Changes from Version 1.x
|
|
||||||
|
|
||||||
WellRESTed 2 brings a streamlined API and extra flexibility. In order to make the kinds of improvements I wanted to make, I had to take a sledge hammer to backwards compatabiliy. If you're project is using a 1.x version, please be sure to set you Composer file to use 1.x until you are ready to migrate.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"require": {
|
|
||||||
"pjdietz/wellrested": "1.*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is not a comprehensive list, but here I'll outline some of the major departures from version 1 to help you port to the new version.
|
|
||||||
|
|
||||||
## Routes
|
|
||||||
|
|
||||||
Routes are redesigned for version 2.
|
|
||||||
|
|
||||||
### URI Templates
|
|
||||||
|
|
||||||
In version 1, `Route` included a static method for creating a route using a URI template. Version 2 has a specific class for URI template routes.
|
|
||||||
|
|
||||||
**Version 1**
|
|
||||||
```php
|
|
||||||
$route = Route::newFromUriTemplate('/things/', 'ThingsHandler');
|
|
||||||
```
|
|
||||||
|
|
||||||
**Version 2**
|
|
||||||
```php
|
|
||||||
$route = new TemplateRoute('/things/', 'ThingsHandler');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Regular Expressions
|
|
||||||
|
|
||||||
Version 1's `Route` expected you to use regular expressions. To do this in version 2, use the `RegexRoute`.
|
|
||||||
|
|
||||||
**Version 1**
|
|
||||||
```php
|
|
||||||
$route = new Route('/^\/cat\//', 'CatHandler');
|
|
||||||
```
|
|
||||||
|
|
||||||
**Version 2**
|
|
||||||
```php
|
|
||||||
$route = new RegexRoute('/^\/cat\//', 'CatHandler');
|
|
||||||
```
|
|
||||||
|
|
||||||
Version 2 also includes the `StaticRoute` class for when you want to match on an exact path.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new StaticRoute('/cat/', 'CatHandler');
|
|
||||||
```
|
|
||||||
|
|
||||||
See [Routes](routes.md) for more information.
|
|
||||||
|
|
||||||
## Interfaces
|
|
||||||
|
|
||||||
I whittled the number of interfaces down to three:
|
|
||||||
- [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php)
|
|
||||||
- [`RequestInterface`](../src/pjdietz/WellRESTed/Interfaces/RequestInterface.php)
|
|
||||||
- [`ResponseInterface`](../src/pjdietz/WellRESTed/Interfaces/ResponseInterface.php)
|
|
||||||
|
|
||||||
(`RoutableInterface`, `RouteInterface`, `RouteTargetInterface`, `RouterInterface` are all removed.)
|
|
||||||
|
|
||||||
Version 2's design is centered around [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php). This new approach both simplifies the API, but also adds a great deal of flexibility.
|
|
||||||
|
|
||||||
See [HandlerInterface](handler-interface.md) to learn more.
|
|
||||||
|
|
||||||
## No Magic Accessors
|
|
||||||
|
|
||||||
I removed the magic property methods so that I could make better use of interfaces. This means you'll need to use accessors where you previously could have used properties.
|
|
||||||
|
|
||||||
**Version 1**
|
|
||||||
```php
|
|
||||||
$request->statusCode = 200;
|
|
||||||
```
|
|
||||||
|
|
||||||
**Version 2**
|
|
||||||
```php
|
|
||||||
$request->setStatusCode(200);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Making Requests
|
|
||||||
|
|
||||||
I moved the cURL functionality that allows you to make a request out of the `Request` class and into [`Client`](../src/pjdietz/WellRESTed/Client.php).
|
|
||||||
|
|
||||||
**Version 1**
|
|
||||||
```php
|
|
||||||
// Prepare a request.
|
|
||||||
$rqst = new Request('http://my.api.local/resources/');
|
|
||||||
|
|
||||||
// Make the request.
|
|
||||||
$resp = $rqst->request();
|
|
||||||
```
|
|
||||||
|
|
||||||
**Version 2**
|
|
||||||
```php
|
|
||||||
// Prepare a request.
|
|
||||||
$rqst = new Request('http://my.api.local/resources/');
|
|
||||||
|
|
||||||
// Make the request.
|
|
||||||
$client = new Client();
|
|
||||||
$resp = $client->request(rqst);
|
|
||||||
```
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
# HandlerInterface
|
|
||||||
|
|
||||||
Much of WellRESTed 2 centers around the [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php) which has only one method that you need to implement:
|
|
||||||
|
|
||||||
```php
|
|
||||||
/**
|
|
||||||
* @param RequestInterface $request The request to respond to.
|
|
||||||
* @param array|null $args Optional additional arguments.
|
|
||||||
* @return ResponseInterface The handled response.
|
|
||||||
*/
|
|
||||||
public function getResponse(RequestInterface $request, array $args = null);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Hello, World!
|
|
||||||
|
|
||||||
Here's a really simplistic example of a "hello world" handler.
|
|
||||||
|
|
||||||
```php
|
|
||||||
class HelloWorldHandler implements HandlerInterface
|
|
||||||
{
|
|
||||||
public function getResponse(RequestInterface $request, array $args = null)
|
|
||||||
{
|
|
||||||
$response = new Response(200, "Hello, world!");
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can plug this into a [`Router`](../src/pjdietz/WellRESTed/Router.php), and the router will always respond with "Hello, world!".
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router = new Router();
|
|
||||||
$router->addRoute(new HelloWorldHandler());
|
|
||||||
$router->respond();
|
|
||||||
```
|
|
||||||
|
|
||||||
### But there's no route?
|
|
||||||
|
|
||||||
Here's the cool thing about how routing works in WellRESTed 2: The route classes implement [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php). When the `Router` iterates through its list of routes, it calls `getResponse()` on each one until it gets a non-`null` return value. At this point, it returns that response (or outputs it in the case of `Router::respond()`).
|
|
||||||
|
|
||||||
Each time the router calls `getResponse()` on a route that doesn't match request, the route returns `null` to indicate that something else will need to handle this.
|
|
||||||
|
|
||||||
Let's add another class to demonstrate.
|
|
||||||
|
|
||||||
```php
|
|
||||||
class DoNothingHandler implements HandlerInterface
|
|
||||||
{
|
|
||||||
public function getResponse(RequestInterface $request, array $args = null)
|
|
||||||
{
|
|
||||||
// THE GOGGLES DO NOTHING!
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router = new Router();
|
|
||||||
$router->addRoute(new DoNothingHandler());
|
|
||||||
$router->addRoute(new HelloWorldHandler());
|
|
||||||
$router->respond();
|
|
||||||
```
|
|
||||||
|
|
||||||
This router will still always respond with "Hello, world!" even though the router will try `DoNothingHandler` first because `DoNothingHandler` returns `null`.
|
|
||||||
|
|
||||||
### 404'ed!
|
|
||||||
|
|
||||||
If none of the routes in a router return a non-`null` value, what happens?
|
|
||||||
|
|
||||||
If you're calling `Router::respond()`, you will **always** get a response. `Router::respond()` is a shorthand method that will output the response made in `Router::getNoRouteResponse()` if it gets through its entire route table and finds no matches.
|
|
||||||
|
|
||||||
If you want to customize the default 404 response, you can either subclass `Router` and redefine `Router::getNoRouteResponse()`, or you can create a [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php) like our `HelloWorldHandler` that always returns a response with a `404 Not Found` status code and add it to the router **last**. (Remember: a router evaluates its routes in the order you add them.)
|
|
||||||
|
|
||||||
```php
|
|
||||||
class NotFoundHandler implements HandlerInterface
|
|
||||||
{
|
|
||||||
public function getResponse(RequestInterface $request, array $args = null)
|
|
||||||
{
|
|
||||||
$response = new Response(400);
|
|
||||||
$response->setBody("No resource at " $request->getPath());
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router = new Router();
|
|
||||||
$router->addRoute(/*...Real route... */);
|
|
||||||
$router->addRoute(/*...Real route... */);
|
|
||||||
$router->addRoute(/*...Real route... */);
|
|
||||||
$router->addRoute(new NotFoundHandler());
|
|
||||||
$router->respond();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Nested Routers
|
|
||||||
|
|
||||||
`Router::respond()` is a shorthand method that wraps `Router::getResponse()`, which [`Router`](../src/pjdietz/WellRESTed/Router.php) must have because it too implements [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php). This means that you can break your router into subrouters.
|
|
||||||
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router = new Router();
|
|
||||||
$router->addRoutes(array(
|
|
||||||
new TemplateRoute("/cats/*", "CatRouter"),
|
|
||||||
new TemplateRoute("/dogs/*", "DogRouter"),
|
|
||||||
new NotFoundHandler()
|
|
||||||
));
|
|
||||||
$router->repond();
|
|
||||||
```
|
|
||||||
|
|
@ -1,171 +0,0 @@
|
||||||
# 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` | [`ResponseInterface`](../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`](../src/pjdietz/WellRESTed/Exceptions/HttpExceptions.php) and setting the exception's `$code` to the status code and `$messge` to a default message.
|
|
||||||
|
|
||||||
## Custom Base Handler
|
|
||||||
|
|
||||||
When building your API, you may want to subclass [`Handler`](../src/pjdietz/WellRESTed/Handler.php) with your own abstract class that adds methods for authenticaion, supports some extra verbs, presents custom errors, adds addiitonal headers, etc. Then, you can derive all of your concrete handlers from that class.
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
abstract class MyHandler extends \pjdietz\WellRESTed\Handler
|
|
||||||
{
|
|
||||||
protected function buildResponse()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
// Add support for a custom HTTP verb.
|
|
||||||
switch ($this->request->getMethod()) {
|
|
||||||
case 'SNIFF':
|
|
||||||
$this->sniff();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
self::buildResponse();
|
|
||||||
}
|
|
||||||
} catch (UnauthorizedException $e) {
|
|
||||||
// Catch 401 errors and call a method to do something with them.
|
|
||||||
$this->responseToUnauthorized($e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a header to all responses.
|
|
||||||
$this->response->addHeader("X-Custom-Header", "Hello, world!");
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected function sniff();
|
|
||||||
|
|
||||||
protected function responseToUnauthorized(HttpException $e)
|
|
||||||
{
|
|
||||||
$this->response->setStatusCode($e->getCode());
|
|
||||||
$this->response->setBody("Y U NO SEND CREDENTIALS?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
# Routes
|
|
||||||
|
|
||||||
WellRESTed comes with a few route classes:
|
|
||||||
|
|
||||||
- [`StaticRoute`](../src/pjdietz/WellRESTed/Routes/StaticRoute.php): Matches request paths exactly
|
|
||||||
- [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php): Matches URI templates
|
|
||||||
- [`RegexRoute`](../src/pjdietz/WellRESTed/Routes/RegexRoute.php): Matches a custom regular expression
|
|
||||||
|
|
||||||
Each works basically the same way: It first checks to see if it is a match for the request. If it's a match, it instantiates a specific class implementing the [`HandlerInterface`](../src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php) (autoloading the class, if needed). Finally, it uses the handler class to provide a response.
|
|
||||||
|
|
||||||
## StaticRoute
|
|
||||||
|
|
||||||
Use a [`StaticRoute`](../src/pjdietz/WellRESTed/Routes/StaticRoute.php) when you know the exact path you want to handle. This route will match only requests to `/cats/`.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new StaticRoute("/cats/", "CatHandler");
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also make a [`StaticRoute`](../src/pjdietz/WellRESTed/Routes/StaticRoute.php) that matches multiple exact paths. For example, suppose you have a multi-use `AnimalHandler` that you want to invoke to handle requests for `/cats/`, `/dogs/`, and `/birds/`. You can make this by passing an array instead of a string as the first parameter.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new StaticRoute(array("/cats/", "/dogs/", "/birds/"), "AnimalHandler");
|
|
||||||
```
|
|
||||||
|
|
||||||
## TemplateRoute
|
|
||||||
|
|
||||||
[`StaticRoute`](../src/pjdietz/WellRESTed/Routes/StaticRoute.php) is the best choice if you know the exact path up front. But, what if you want to handle a path that includes a variable? That's where the [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) comes in.
|
|
||||||
|
|
||||||
Here's a route that will match a request to a specific cat by ID and send it to a `CatItemHandler`.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new TemplateRoute("/cats/{id}", "CatItemHandler");
|
|
||||||
```
|
|
||||||
|
|
||||||
This will match `/cats/1`, `/cats/99`, `/cats/molly`, etc.
|
|
||||||
|
|
||||||
A [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) uses a URI template to match a request. To include a variable in your template, enclose it in `{}`. The variable will be extracted and made available for the handler in the handler's `args` member.
|
|
||||||
|
|
||||||
```php
|
|
||||||
class CatItemHandlder extends \pjdietz\WellRESTed\Handler
|
|
||||||
{
|
|
||||||
protected function get()
|
|
||||||
{
|
|
||||||
// Access the {id} variable from the $this->args member.
|
|
||||||
$id = $this->args["id"];
|
|
||||||
// ...Do something with the {id}.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For the paths `/cats/1`, `/cats/99`, `/cats/molly`, the value of `$this->args["id"]` will be `"1"`, `"99"`, or `"molly"`.
|
|
||||||
|
|
||||||
Your template may have multiple variables. Be sure to give each a unique name.
|
|
||||||
|
|
||||||
Here the handler will have access to `$this->args["catId"]` and `$this->args["dogId"]`.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new TemplateRoute("/cats/{catId}/{dogId}", "CatItemHandler");
|
|
||||||
```
|
|
||||||
|
|
||||||
### Default Variable Pattern
|
|
||||||
|
|
||||||
By default, the [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) will accept for a variable any value consisting of numbers, letters, underscores, and hyphens. You can change this behavior by passing a pattern to use as the third parameter of the constructor. Here we'll restrict the template to match only numeric values.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new TemplateRoute("/cats/{id}", "CatItemHandler", TemplateRoute::RE_NUM);
|
|
||||||
```
|
|
||||||
|
|
||||||
This will match `/cats/1` or `/cats/99`, but NOT `/cats/molly`.
|
|
||||||
|
|
||||||
### Pattern Constants
|
|
||||||
|
|
||||||
The [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) includes constants for some common situations. The value of each constant is a partial regular expression. You can use one of the constants, or provide your own partial regular expression.
|
|
||||||
|
|
||||||
|
|
||||||
| Constant | Pattern | Description |
|
|
||||||
| ------------ | ----------------- | ----------- |
|
|
||||||
| `RE_SLUG` | `[0-9a-zA-Z\-_]+` | **(Default)** "URL-friendly" characters such as numbers, letters, underscores, and hyphens |
|
|
||||||
| `RE_NUM` | `[0-9]+` | Digits only |
|
|
||||||
| `RE_ALPHA` | `[a-zA-Z]+` | Letters only |
|
|
||||||
| `RE_ALPHANUM` | `[0-9a-zA-Z]+` | Letters and digits |
|
|
||||||
|
|
||||||
### Variable Patterns Array
|
|
||||||
|
|
||||||
You can also set a different pattern for each variable. To do this, pass an array to the [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) constructor as the fourth parameter. The array must have variable names as keys and patterns as values.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$patterns = array(
|
|
||||||
"id" => TemplateRoute::RE_NUM,
|
|
||||||
"name" => TemplateRoute::RE_ALPHA
|
|
||||||
);
|
|
||||||
$route = new TemplateRoute(
|
|
||||||
"/cats/{id}/{name}/{more}",
|
|
||||||
"CatItemHandler",
|
|
||||||
TemplateRoute::RE_ALPHANUM,
|
|
||||||
$patterns);
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `{id}` will need to match digits and `{name}` must be all letters. Since `{more}` is not explicitly provided in the `$patterns` array, it uses the default `TemplateRoute::RE_ALPHANUM` passed as the third parameter.
|
|
||||||
|
|
||||||
### Wildcard
|
|
||||||
|
|
||||||
If you want to match all requests with paths that start with a given template, end your template with `*`. This is useful for handing groups of requests off to subrouters.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new TemplateRoute("/cats/*", "CatRouter");
|
|
||||||
```
|
|
||||||
|
|
||||||
This will match `/cats/`, `/cats/21`, `/cats/with/extra/path/components/`, etc.
|
|
||||||
|
|
||||||
The `*` wildcard may only appear at the **end** of your template.
|
|
||||||
|
|
||||||
## RegexRoute
|
|
||||||
|
|
||||||
If [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php) doesn't give you enough control, you can make a route that matches a regular expression using a [`RegexRoute`](../src/pjdietz/WellRESTed/Routes/RegexRoute.php).
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new RegexRoute("~/cat/[0-9]+~", "CatHandler")
|
|
||||||
```
|
|
||||||
|
|
||||||
This will match `/cat/102`, `/cat/999`, etc. To make this more useful, we can add a capture group. The captures are made available to the handler as the `$args` member, as with the URI template variables for the [`TemplateRoute`](../src/pjdietz/WellRESTed/Routes/TemplateRoute.php)
|
|
||||||
|
|
||||||
Note that the entire matched path will always be the `0` item, and captured groups will begin at `1`.
|
|
||||||
|
|
||||||
So this route...
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new RegexRoute("~/cat/([0-9]+)~", "CatHandler")
|
|
||||||
```
|
|
||||||
|
|
||||||
...with the path `/cat/99` creates this array of matches:
|
|
||||||
|
|
||||||
```
|
|
||||||
Array
|
|
||||||
(
|
|
||||||
[0] => /cat/99
|
|
||||||
[1] => 99
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also used named capture groups like this:
|
|
||||||
|
|
||||||
|
|
||||||
```php
|
|
||||||
$route = new RegexRoute("~/cat/(?<id>[0-9]+)~", "CatHandler")
|
|
||||||
```
|
|
||||||
|
|
||||||
The path `/cat/99` creates this array of matches:
|
|
||||||
|
|
||||||
```
|
|
||||||
Array
|
|
||||||
(
|
|
||||||
[0] => /cat/99
|
|
||||||
[1] => 99
|
|
||||||
[id] => 99
|
|
||||||
)
|
|
||||||
```
|
|
||||||
Loading…
Reference in New Issue