WellRESTed ========== WellRESTed provides classes to help you create RESTful APIs and work with HTTP requests and responses. Requirements ------------ - PHP 5.3 - [Composer](http://getcomposer.org/) for autoloading - [PHP cURL](http://php.net/manual/en/book.curl.php) for making requests Install ------- Add an entry for "pjdietz/wellrested" to your composer.json file's **require** property. If you are not already using Composer, create a file in your project called **composer.json** with the following content: ```json { "require": { "pjdietz/wellrested": "1.*" } } ``` Use Composer to download and install WellRESTed. Run these commands from the directory containing the composer.json file. ```bash $ curl -s https://getcomposer.org/installer | php $ php composer.phar install ``` You can now use WellRESTed by including the autoload.php file generated by Composer. (vendor/autoload.php) Examples -------- ### Routing 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(); $resp->statusCode = 200; $resp->setHeader('Content-type', 'text/plain'); $resp->body = 'Hello world!'; $resp->respond(); exit; ``` 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(); if ($rqst->method === 'PUT') { $obj = json_decode($rqst->body); // Do something with the JSON sent as the message body. } ``` The Request class can also make a request to another server and provide the response as a Respones object. (This feature requires [PHP cURL](http://php.net/manual/en/book.curl.php).) ```php // Prepare a request. $rqst = new \pjdietz\WellRESTed\Request(); $rqst->uri = 'http://my.api.local/resources/'; $rqst->method = 'POST'; $rqst->body = json_encode($newResource); // Make the request. $resp = $rqst->request(); // Read the response. if ($resp->statusCode === 201) { // The new resource was created. $newResource = json_decode($resp->body); } ``` More Examples --------------- For more examples, see the project [pjdietz/wellrested-samples](https://github.com/pjdietz/wellrested-samples). Copyright and License --------------------- Copyright © 2013 by PJ Dietz Licensed under the [MIT license](http://opensource.org/licenses/MIT)