PhpRiot
News Archive
Related Articles
PhpRiot Newsletter
Your Email Address:

More information

Building a RESTful Web API with PHP and Apify

Note: This article was originally published at Planet PHP on 12 September 2011.
Planet PHP

Today, it is my pleasure to announce the release of Apify 1.0. You can download this release from GitHub. Thanks to everyone who has contributed to this release in any way.

Apify is a small and powerful open source library that delivers new levels of developer productivity by simplifying the creation of RESTful architectures. You can see it in action here. Web services are a great way to extend your web application, however, adding a web API to an existing web application can be a tedious and time-consuming task. Apify takes certain common patterns found in most web services and abstracts them so that you can quickly write web APIs without having to write too much code.

Apify exposes similar APIs as the Zend Framework, so if you are familiar with the Zend Framework, then you already know how to use Apify. Take a look at the UsersController class.

Building a RESTful Web API

In Apify, Controllers handle incoming HTTP requests, interact with the model to get data, and direct domain data to the response object for display. The full request object is injected via the action method and is primarily used to query for request parameters, whether they come from a GET or POST request, or from the URL.

Creating a RESTful Web API with Apify is easy. Each action results in a response, which holds the headers and document to be sent to the user's browser. You are responsible for generating the response object inside the action method.

class UsersController extends Controller { public function indexAction($request) { // 200 OK return new Response(); } }

The response object describes the status code and any headers that are sent. The default response is always 200 OK, however, it is possible to overwrite the default status code and add additional headers:

class UsersController extends Controller { public function indexAction($request) { $response = new Response(); // 401 Unauthorized $response-setCode(Response::UNAUTHORIZED); // Cache-Control header $response-setCacheHeader(3600); // ETag header $response-setEtagHeader(md5($request-getUrlPath())); // X-RateLimit header $limit = 300; $remaining = 280; $response-setRateLimitHeader($limit, $remaining); // Raw header $response-addHeader('Edge-control: no-store'); return $response; } }

Content Negotiation

Apify supports sending responses in html, XML, RSS and JSON. In addition, it supports JSONP, which is JSON wrapped in a custom JavaScript function call. There are 3 ways to specify the format you want:

  • Appending a format extension to the end of the URL path (.html, .json, .rss or .xml)
  • Specifying the response format in the query string. This means a format=xml or format=json parameter for XML or JSON, respectively, which will override the Accept header if there is one.
  • Sending a standard Accept header in your request (text/html, application/xml or application/json).

The response object takes one parameter: acceptable_types. This parameter indicates that the response only serves certain content types.

class UsersController extends Controller { public function indexAction($request) { // only serve JSON and XML return new Response(array('json', 'xml')); } }

Apify will render the error message according to the format of the request.

class UsersController extends Controller { public function indexAction($request) { $response = new Response(array('json', 'xml')); if (! $request-hasParam('api_key')) { return new Exception('Missing parameter: api_key', Response::FORBIDDEN); } $response-api_key = $request-getParam('api_key'); return $response; } }

Request

GET /users.json

Response

Status: 403 Forbidden Content-Type: application/json { "code": 403, "error": { "message": "Missing parameter: api_key", "type": "Exception" } }

Resourceful Routes

Apify supports REST style URL mappings where you can map different HTTP methods, such as GET, POST, PUT and DELETE, to different actions in a controller. This basic REST design principle establ

Truncated by Planet PHP, read more at the original (another 7073 bytes)