From 20fb124cd53b20b2747c82fb9050f97c0ecaf221 Mon Sep 17 00:00:00 2001 From: PJ Dietz Date: Sun, 19 May 2013 12:54:57 -0400 Subject: [PATCH] Rewrite README --- README.md | 119 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 78 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 176189d..c0f5c3a 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,84 @@ You can now use WellRESTed by including the autoload.php file generated by Compo Examples -------- -### Responses +### Routing -Use a Response instance to build a response and send output. The Response class makes it easy to set the status code, add headers, and set the response body. +WellRESTed's primary goal is to facilitate mapping of URIs to classes that will provide or accept representations. To do this, create a Router instance and load it up with some Routes. Each Route is simply a mapping of a URI pattern to a classname. The classname represents the Handler class which the router will dispatch at the time it recieves a request for the given URI. The handlers are never loaded until they are needed. + +Here's an example of a Router that will handle two URIs: + +```php +// Build the router. +$myRouter = new Router(); +$myRouter->addRoute(Route::newFromUriTemplate('/things/', 'ThingCollectionHandler')); +$myRouter->addRoute(Route::newFromUriTemplate('/things/{id}', 'ThingItemHandler')); + +// Determine and output the response. +$response = $router->getResponse(); +$response->respond(); +``` + +When you create your Handler subclass, you will provide a method for each HTTP verb you would like the endpoint to support. For example, if /things/ should support GET, you would override the get() method. For POST, post(), etc. + +If your endpoint should reject particular verbs, no worries. The Handler base class defines the default verb-handling methods to respond with a 405 Method Not Allowed status. + +Here's a simple Handler that matches the first endpoint, /things/. + +```php +class ThingCollectionHandler extends \pjdietz\WellRESTed\Handler +{ + protected function get() + { + // Read some things from the database, cache, whatever. + // ... + + // Set the values for the instance's reponse member. This what the + // Router will eventually use to output a response to the client. + $this->response->statusCode = 200; + $this->response->setHeader('Content-Type', 'application/json'); + $this->response->body = json_encode($data); + } + + protected function post() + { + // Read from the instance's request member and store a new Thing. + // ... + + // Build a reponse to send to the client. + $this->response->statusCode = 201; + $this->response->body = 'You added a thing!'; + } +} +``` + +This Handler works with the second endpoint, /things/{id}. The pattern for this endpoing has a variable in it ({id}). The Handler can access path variables through its args member, which is an associative array of variable from the URI. + +```php +class ThingItemHandler extends \pjdietz\WellRESTed\Handler +{ + protected function get() + { + // Lookup a Thing based on $this->args['id'] + // ... + + if ($thing) { + // The Thing exists! Let's output a representation. + $this->response->statusCode = 200; + $this->response->setHeader('Content-Type', 'application/json'); + $this->response->body = json_encode($thing); + } else { + // The ID did not match anything. + $this->response->statusCode = 404; + $this->response->setHeader('Content-Type', 'text/plain'); + $this->response->body = 'No thing with id ' . $this->args['id']; + } + } +} +``` + +### Requests and Responses + +You've already seen a Response in use in the examples above. You can also use Responses outside of Handlers. Let's take a look at creating a new Response, setting a headers, supplying the body, and outputting. ```php $resp = new \pjdietz\WellRESTed\Response(); @@ -54,11 +129,7 @@ $resp->respond(); exit; ``` -### Requests - -Use the Request class to read information about the request sent to the server. You can read the headers, method, and message body. - -Request provides a singleton instance representing the request sent to the current script. +The Request class goes hand-in-hand with the Response class. Again, this is used in the Handler class to read the information from the request being handled. From outside the context of a Handler, you can also use the Request class to read info for the request sent to the server. ```php $rqst = \pjdietz\WellRESTed\Request::getRequest(); @@ -88,40 +159,6 @@ if ($resp->statusCode === 201) { } ``` -### URIs and Routing - -WellRESTed also provides several classes to facilitate working with resource-based URIs. You can create your own regular expressions to match the URIs, or you can use URI templates. - -Here's an example of a Router subclass. The subclass examines a request URI, compares it against a series of URI templates, and matches the request to a particular Handler class. - -For more information on URI templates, see [RFC 6570](http://tools.ietf.org/html/rfc6570). - -```php -/** - * Loads and instantiates handlers based on URI. - */ -class MyRouter extends \pjdietz\WellRESTed\Router -{ - public function __construct() - { - parent::__construct(); - - // Match any request to the URI "/things/" - // Send it to a handler for collections of thing objects. - $this->addRoute(Route::newFromUriTemplate('/things/', 'ThingCollectionHandler')); - - // Match any request to "/things/" followed by a variable. - // Send the request to a handler for one thing object. - // The ThingItemHandler will receive an array containing an "id" key - // and the value from the URI. - $this->addRoute(Route::newFromUriTemplate('/things/{id}', 'ThingItemHandler')); - - // ...Add as manu routes as you like here... - } -} - -``` - More Examples ---------------