How to configure a RESTful Backbone.js and PHP API

How to configure a RESTful Backbone.js and PHP API

 

Backbone.js is one of the many javascript frameworks out there. Thats fine, we’re not here to talk about that ;). When trying to create a RESTful PHP API what we care about is how do we receive the data and what our endpoints should look like. Typical API endpoints look like this:

HTTP methods
Uniform Resource Locator (URL) GET PUT POST DELETE
Collection, such as http://api.example.com/resources/ List the URIs and perhaps other details of the collection’s members. Replace the entire collection with another collection. Create a new entry in the collection. The new entry’s URI is assigned automatically and is usually returned by the operation.[17] Delete the entire collection.
Element, such as http://api.example.com/resources/item17 Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type. Replace the addressed member of the collection, or if it does not exist, create it. Not generally used. Treat the addressed member as a collection in its own right and create a new entry within it.[17] Delete the addressed member of the collection.

(Wikipedia)

Basically, these are “clean” URLs that our API knows what to do with and what is expected when they are hit. HTTP has many methods built-in that are available but there are Five that we need to concern ourselves with and tell PHP what to do once NGINX is configured.

 

NGINX Clean Endpoint Configuration

This relatively straight forward but can be intimidating. Here is the configuration for my API.

location /api/v1 {
    index index.php;
    root /var/www/lifeboat/current;
    rewrite (.*) /api/v1/index.php?$query_string;

    location ~\.php$ {
        fastcgi_index index.php;
        try_files $uri =404;
        include /etc/nginx/fastcgi.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        include fastcgi_params;
    }
}

Let’s break this down.

  1. We are using DeployBot on this server so when we push to GitHub the code will deploy automatically. DeployBot places the latest code in a symlinked dir called “current“.  Your setup will very and probably just be “/var/www/your-project”. The location alias that of “api/v1″ tells NGINX that anything requested from this URI should follow these specific rules below.
  2. The rewrite is where the magic happens.  We are telling NGINX to take anything requested with that URI and use index.php as the index, taking any $query_string (api/v1/function/data/password) and pass it into index.php. Once we have the data passed in we can take it and do what we want.
  3. The last location block is standard for using PHP.  I am using PHP 7 on this server and the fastcgi_pass might look different if you are using anything else.

 

HTTP Request Methods

For our API we need PHP to look at GET,PUT,POST,DELETE.  These are not the same as $_GET and $_POST, these are the special HTTP methods and need to be handled through $_SERVER[‘REQUEST_METHOD’]. For example:

switch ($_SERVER['REQUEST_METHOD']) {
    case "POST":
    case "PUT": { 
        //POST or PUT something
    break;
    }
    case "GET": {
        //GET something
    break;
    }
    case "DELETE": {
        //DELETE something
    break;
    }
case "OPTIONS": {
    header("HTTP/1.0 200");
    break;
    }
}//Switch

This is pretty straight forward as well, but you will never get to this point unless you set your HEADERs correctly.

 

HTTP Headers

Backbone requires that you allow these HTTP Methods to be available on your server. Normally you would not want javascript to call functions on your server. That sounds like a bad Idea unless you want it to happen (you can take care of security elsewhere).  In PHP you must set these before you send anything back.

    header('Access-Control-Allow-Origin: *');
    header("Access-Control-Allow-Credentials: true");
    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT, PATCH,x-http-method-override');
    header('content-type: application/json; charset=utf-8');
    header('Access-Control-Max-Age: 86400');

After this, you should be able to simply return any data (jSON encoded) and if your backbone.js front-end knows what to do with jSON then you are good to go.

Leave a Reply

Your email address will not be published. Required fields are marked *