New README in progress
This commit is contained in:
parent
64ef9cc4e7
commit
bc966f5924
100
README.md
100
README.md
|
|
@ -5,13 +5,6 @@ WellRESTed
|
|||
|
||||
WellRESTed is a micro-framework for creating RESTful APIs in PHP. It provides a lightweight yet powerful routing system and classes to make working with HTTP requests and responses clean and easy.
|
||||
|
||||
Version 2
|
||||
---------
|
||||
|
||||
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](https://github.com/pjdietz/wellrested/wiki/Changes-from-Version-1) if you are migrating from a previous 1.x version of WellRESTed.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
|
|
@ -42,37 +35,69 @@ $ php composer.phar install
|
|||
You can now use WellRESTed by including the `vendor/autoload.php` file generated by Composer.
|
||||
|
||||
|
||||
Examples
|
||||
Overview
|
||||
--------
|
||||
|
||||
### Routing
|
||||
### Routing and Routes
|
||||
|
||||
WellRESTed's primary goal is to facilitate mapping of URIs to classes that will provide or accept representations. To do this, create a [`Router`](src/pjdietz/WellRESTed/Router.php) instance and load it up with some routes. Each route is simply a mapping of a path or path pattern to a class name. The class name represents the "handler" (any class implementing [`HandlerInterface`](src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php) ) which the router will dispatch when it receives a request for the given URI. **The handlers are never instantiated or loaded unless they are needed.**
|
||||
WellRESTed's primary goal is to facilitate mapping of URIs to classes that will provide or accept representations. To do this, create a [`Router`](src/pjdietz/WellRESTed/Router.php) instance and load it up with some routes.
|
||||
|
||||
```php
|
||||
// Build the router.
|
||||
$myRouter = new Router();
|
||||
$myRouter->addRoutes(array(
|
||||
new StaticRoute("/", "\\myapi\\Handlers\\RootHandler"),
|
||||
new StaticRoute("/cats/", "\\myapi\\Handlers\\CatCollectionHandler"),
|
||||
new TemplateRoute("/cats/{id}/", "\\myapi\\Handlers\\CatItemHandler")
|
||||
));
|
||||
$myRouter->add(
|
||||
["/exact/", $exactHandler],
|
||||
["/prefix/*", $prefixHandler],
|
||||
["/template/{id}/", $templateHandler],
|
||||
["~/regex/([0-9+])~", $regexHandler],
|
||||
);
|
||||
$myRouter->respond();
|
||||
```
|
||||
|
||||
See [Routes](https://github.com/pjdietz/wellrested/wiki/Routes) to learn about the various route classes.
|
||||
Each route maps a path to a handler. The path may be:
|
||||
|
||||
- An exact match to a path (fastest, least powerful)
|
||||
- A prefix (ending with `*`)
|
||||
- A URI template with variables indicated with curly braces (ex: `{variable}`)
|
||||
- A regular expression (slowest, most powerful)
|
||||
|
||||
#### Optimized Route Lookup
|
||||
Template and Regex routes will forward variables or captures to their handlers. Template routes can also be customized to restrict variables to match specific patterns. (TODO LINK)
|
||||
|
||||
StaticRoute and PrefixRoute routes are optimized by providing a direct lookup from path to handler. This is different from convential lookups because a match must be found by iterating through the entire list of routes in the router. This reduces the lookup complexity from O(n)—linear—to O(1)—constant.
|
||||
The handler may be any of the following:
|
||||
- An instance that implements [`HandlerInterface`](src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php)
|
||||
- A string containing the fully qualified name of a `HandlerInterface` concrete class
|
||||
- A callable that returns a `HandlerInterface` concrete class
|
||||
|
||||
The best choices are strings and callables because they delay instantiation until the last instant. If your class is autoloaded, the class never needs to be loaded or instantiated until it is needed.
|
||||
|
||||
To illustrate, image you have a namespace `\MyApi` with several classes inside that implement `HandlerInterface`.
|
||||
|
||||
```php
|
||||
// Build the router.
|
||||
$myRouter = new Router();
|
||||
$myRouter->add(
|
||||
["/instance/", new \MyApi\InstanceHandler()],
|
||||
["/string/", '\MyApi\StringHandler'],
|
||||
["/callable/", function () {
|
||||
return new \MyApi\CallableHandler();
|
||||
}]
|
||||
);
|
||||
$myRouter->respond();
|
||||
```
|
||||
|
||||
While the callable approach may look a bit weird, it's very powerful, and makes dependency injection very easy. (TODO LINK)
|
||||
|
||||
### Handlers
|
||||
|
||||
Any class that implements [`HandlerInterface`](src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php) may be the handler for a route. This could be a class that builds the actual response, or it could be another [`Router`](src/pjdietz/WellRESTed/Router.php).
|
||||
|
||||
For most cases, you'll want to use a subclass of the [`Handler`](src/pjdietz/WellRESTed/Handler.php) class, which provides methods for responding based on HTTP method. When you create your [`Handler`](src/pjdietz/WellRESTed/Handler.php) subclass, you will implement a method for each HTTP verb you would like the endpoint to support. For example, if `/cats/` should support `GET`, you would override the `get()` method. For `POST`, `post()`, etc.
|
||||
When a router dispatches a request to a handler, it calls the handler's `getResponse()` method, passing along the request and an array of extra arguments. These extra arguments may be captures from a regular expression route, variables from a URI template route, or any other arbitrary pieces of information you want to pass to the handler.
|
||||
|
||||
The handler builds and returns a [`ResponseInterface`](src/pjdietz/WellRESTed/Interfaces/ResponseInterface.php). Or, the handler may return `null` to indicate that it won't be handling the request after all.
|
||||
|
||||
#### Handler Class
|
||||
|
||||
WellRESTed provides the abstract class [`Handler`](src/pjdietz/WellRESTed/Handler.php) which you may subclass for your handlers. This class provides methods for responding based on HTTP method. When you create your [`Handler`](src/pjdietz/WellRESTed/Handler.php) subclass, you will implement a method for each HTTP verb you would like the endpoint to support. For example, if `/cats/` should support `GET`, you would override the `get()` method. For `POST`, `post()`, etc.
|
||||
|
||||
Here's a simple Handler that allows `GET` and `POST`.
|
||||
|
||||
|
|
@ -161,43 +186,6 @@ if ($resp->getStatusCode() === 201) {
|
|||
}
|
||||
```
|
||||
|
||||
### Building Routes with JSON
|
||||
|
||||
WellRESTed also provides a class to construct routes for you based on a JSON description. Here's an example:
|
||||
|
||||
```php
|
||||
$json = <<<'JSON'
|
||||
{
|
||||
"handlerNamespace": "\\myapi\\Handlers",
|
||||
"routes": [
|
||||
{
|
||||
"path": "/",
|
||||
"handler": "RootHandler"
|
||||
},
|
||||
{
|
||||
"path": "/cats/",
|
||||
"handler": "CatCollectionHandler"
|
||||
},
|
||||
|
||||
{
|
||||
"tempalte": "/cats/{id}",
|
||||
"handler": "CatItemHandler"
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON;
|
||||
|
||||
$builder = new RouteBuilder();
|
||||
$routes = $builder->buildRoutes($json);
|
||||
|
||||
$router = new Router();
|
||||
$router->addRoutes($routes);
|
||||
$router->respond();
|
||||
```
|
||||
|
||||
When you build routes through JSON, you can provide a `handlerNamespace` to be affixed to the front of every handler.
|
||||
|
||||
|
||||
Copyright and License
|
||||
---------------------
|
||||
Copyright © 2015 by PJ Dietz
|
||||
|
|
|
|||
Loading…
Reference in New Issue