API RESTful (and RPC) for PHP with Apigility

by Enrico Zimuel / @ezimuel
Senior Software Engineer - Zend Technologies

About me

I'm a Software Engineer since 1996. I work in the Apigility and Zend Framework team at Zend Technologies. I did research in computer science at Informatics Institute of the University of Amsterdam. I'm the co-author of the Italian books "PHP best practices" and "Javascript best practices". I'm the co-founder of PUG Torino (Italy).

API

API stands for "Application Programming Interface" and as a term, specifies how software should interact.

Generally speaking, when we refer to APIs today, we are referring more specifically to web APIs, those delivered over HyperText Transfer Protocol (HTTP).

REST

REpresentational State Transfer (REST) is not a specification, but an architecture designed around the HTTP specification.

RESTful

REST leverages HTTP's strengths, and builds on:

  • URIs as unique identifiers for resources
  • Rich set of HTTP verbs for operations on resources
  • The ability for clients to specify representation formats they can render
  • Linking between resources to indicate relationships (hypermedia)
  • HATEOAS, Hypermedia As The Engine Of Application State

Glory of REST

When talking about REST, the Richardson Maturity Model is often used to describe the concerns necessary when implementing a well-designed REST API

Advantages of REST

Scalable architecture

Very easy to consume

Reduce client/server coupling

Discoverability

RESTful in practice?

Can be difficult, especially at the beginning

Some questions

  • What representation formats will you expose?
  • How will you report errors?
  • How will you advertise which HTTP methods are available for a given resource?
  • How will you handle features such as authentication?
  • How will you handle hypermedia linking?
  • How will you document what resources are available?

Possible answers

  • What representation formats will you expose? JSON
  • How will you report errors? application/problem+json
  • How will you advertise which HTTP methods are available for a given resource? OPTIONS
  • How will you handle features such as authentication? OAuth2
  • How will you handle hypermedia linking? Hypermedia Application Language (HAL)
  • How will you document what resources are available? Swagger, Apiary.io, API Blueprint, etc

Apigility

Main features

  • RPC and REST
  • JSON (HAL) as default format
  • Error handling (API Problem)
  • Content negotiation
  • Versioning (via URI and Accept header)
  • Filtering and validation
  • Authentication (HTTP Basic/Digest, OAuth2)
  • Interactive documentation (HTML, Swagger)

REST

  • REST is a simple stateless architecture that generally runs over HTTP.
  • It uses URI and HTTP methods to map the different actions (GET, POST, PUT, DELETE).
  • A typical REST API url:
    
    http://domain/api/user[/:user_id]
    

JSON

  • JSON (JavaScript Object Notation), is an open standard format used to transmit data between a server and web application, expressed using Javascript syntax.
  • Example of JSON:
    
    {
        "firstName": "John",
        "lastName": "Smith",
        "age": 25,
        "address": {
            "streetAddress": "21 2nd Street",
            "city": "New York"
        },
        "emails" : [
    	'john.smith@gmail.com',
    	'john@smith.com'
        ]
    }
    

JSON HAL

  • JSON Hypertext Application Language, is a RFC draft proposal (draft-kelly-json-hal-06)
  • Example:
    
    GET /api/user/ezimuel
    
    {
        "_links": {
            "self": {
                "href": "http://domain/api/user/ezimuel"
            }
        }
        "id": "ezimuel",
        "name": "Enrico Zimuel"
    }
    

_embedded


{
    "_links": {
        "self": {
            "href": "http://domain/api/user/ezimuel"
        }
    }
    "id": "ezimuel",
    "name": "Enrico Zimuel",
    "_embedded": {
        "contacts": [
            {
                "_links": {
                    "self": {
                        "href": "http://domain/api/user/mwop"
                    }
                },
                "id": "mwop",
                "name": "Matthew Weier O'Phinney"
            },
            {
                "_links": {
                    "self": {
                        "href": "http://domain/api/user/ralphschindler"
                    }
                },
                "id": "ralphschindler",
                "name": "Ralph Schindler"
            }
        ]
    }
}

Collections


{
    "_links": {
        "self": {
            "href": "http://domain/api/user?page=3"
        },
        "first": {
            "href": "http://domain/api/user"
        },
        "prev": {
            "href": "http://domain/api/user?page=2"
        },
        "next": {
            "href": "http://domain/api/user?page=4"
        },
        "last": {
            "href": "http://domain/api/user?page=133"
        }
    }
    "count": 3,
    "total": 498,
    "_embedded": {
        "users": [
            {
                "_links": {
                    "self": {
                        "href": "http://domain/api/user/mwop"
                    }
                },
                "id": "mwop",
                "name": "Matthew Weier O'Phinney"
            },
            {
                "_links": {
                    "self": {
                        "href": "http://domain/api/user/mac_nibblet"
                    }
                },
                "id": "mac_nibblet",
                "name": "Antoine Hedgecock"
            },
            {
                "_links": {
                    "self": {
                        "href": "http://domain/api/user/spiffyjr"
                    }
                },
                "id": "spiffyjr",
                "name": "Kyle Spraggs"
            }
        ]
    }
}

API Problem

  • API Problem is a RFC draft proposal (draft-nottingham-http-problem-06)
  • Example:
    
    Content-Type: application/problem+json
    
    {
        "detail": "The GET method has not been defined for individual",
        "status": 405,
        "title": "Method Not Allowed",
        "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"
    }
    

Content negotiation

  • Content negotiation is a mechanism defined in the HTTP specification that makes it possible to serve different versions of a document at the same URI.
  • Example:
    
    Accept: application/hal+json, application/json
    

API Versioning

Agility uses two approaches:

  • In the URL, e.g. /api/v1/user
  • By Accept header, e.g. Accept:application/vnd.example.v1+json

Authentication

Apigility supports three different authentication systems: HTTP Basic, HTTP Digest, and OAuth2

Installation

Super easy, just one command:


$ curl -sS https://apigility.org/install | php

Or, if you don't have CURL installed:


$ php -r "readfile('https://apigility.org/install');" | php

Apigility UI

Open the browser to http://localhost:8888

DEMO time

Apigility in action!

Thanks!


Rank this talk on joind https://joind.in/11313


More information on apigility.org

Contact me: enrico [at] zend.com

Follow me: @ezimuel



Creative Commons License
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.