Skip to content
comhon-project edited this page Jul 1, 2020 · 22 revisions

Table of Contents

  1. Preamble
  2. Server
    1. Apache server setup
    2. Entry point
      1. Base path
      2. Requestable models
  3. Client
    1. OPTIONS
    2. GET
      1. Collection's customization
        1. Using query parameters
        2. Using body
    3. HEAD
    4. POST
    5. PUT
    6. DELETE
  4. Media type

Preamble

Comhon! framework permit to build REST API without any line of codes. Actually you just have to define manifest, serialization, options and Comhon! do the rest!

Dockers images are available on Docker Hub in repository comhon/comhon. Each following example may be tested with the image 0.1-sample.
To launch a container locally you just have to execute following command.

> docker run -p 80:8000 comhon/comhon:0.1-sample

Server

We will use and configure an apache server as example.

Apache server setup

We route all HTTP requests to an unique entry point index.php by defining .htaccess file. These two files must be in same directory.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond   %{REQUEST_FILENAME} !-d
    RewriteCond   %{REQUEST_FILENAME} !-f
    RewriteRule   ^((?s).*)$ index.php
</IfModule>

Note that using .htaccess files requires your apache installation to have the AllowOverride All option set.

Entry point

The entry point PHP file must contain at list comhon dependency, the path to configuration file and a call to HTTP request handler.

<?php

use Comhon\Api\RequestHandler;
use Comhon\Object\Config\Config;

// dependencies
require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

// set the path to configuration file
$config_af = __DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.json';
Config::setLoadPath($config_af);

// Comhon framework handle common requests
$response = RequestHandler::handle('/api/comhon');

// send response to client
$response->send();

Base path

The base path is the first parameter pass to RequestHandler::handle() function. This parameter is required. It permit to know which route handler must handle.

For example if we set base path as '/api/comhon' :

  • Following URI will be handled
GET http://localhost:8000/api/comhon/person
PUT http://localhost:8000/api/comhon/woman/1000
  • Following URI will not be handled
PUT http://localhost:8000/comhon/woman/1000
GET http://localhost:8000/api/person
PUT http://localhost:8000/api/comhonwoman/1000

If a URI is not handled, the returned response contain status code 404 and message not handled route

Requestable models

The Requestable models is the second parameter pass to RequestHandler::handle() function. This parameter is optional. It permit to define a list of models that client may request. Requestable models must be an associative array, each key is the route model name and the value is a fully qualified model name.

Example :

[
    "person": "Test\Person",
    "woman": "Test\Person\Woman",
    "man": "Test\Person\Man",
    "house": "Test\House",
]
  • If Requestable models is provided, only specified models are requestables and the URI must contain route model name
GET https://www.mydomain.com/comhon/person/myid
  • If Requestable models is not provided, all models are requestable and the URI must contain fully qualified model name (warning \ must be encoded)
GET https://www.mydomain.com/comhon/Test%5cPerson/myid

Client

Comhon! permit to retrieve, create, update and delete resources very easly. We will eplain how client must use API for each actions.

There are two kind of URI that comhon API is able to handle : Unique and Collection.

Unique

Unique URI look like :
domain / base path / resource model name / resource identifier
It might be use to retrieve, update, or delete a unique resource identified by its identifier.

Collection

Collection URI look like :
domain / base path / resource model name
It might be use to retrieve several resources in same time or to create a unique resource.

OPTIONS

OPTIONS method permit to know allowed methods (in response header Allow). If an options manifest file is defined on server side, options are returned in response body, otherwise the response body is empty. You can choose the response body format by specifying the header Accept. See available media types here. If header Accept is not provided, the default format is JSON.

// request
OPTIONS http://localhost:8000/api/comhon/man/1

// response
200 OK
Allow: OPTIONS, GET, HEAD, PUT, DELETE
// request
OPTIONS http://localhost:8000/api/comhon/man

// response
200 OK
Allow: OPTIONS, GET, HEAD, POST

GET

GET method permit to retrieve one or several resources. You can choose the response body format by specifying the header Accept. See available media types here. If header Accept is not provided, the default format is JSON.

Unique

Unique URI permit to retrieve one resource.

// request
GET http://localhost:8000/api/comhon/man/1
Accept: application/xml

// response
200 OK
Content-Type: application/xml

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="1" firstName="john" lastName="doe">
    <birthPlace>1</birthPlace>
    <father xsi:nil="true"/>
    <mother xsi:nil="true"/>
</root>

Collection

Collection URI permit to retrieve several resource.

// request
GET http://localhost:8000/api/comhon/woman
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {
        "id": 2,
        "firstName": "jane",
        "lastName": "doe",
        "birthPlace": 2,
        "father": null,
        "mother": null
    },
    {
        "id": 3,
        "firstName": "marie",
        "lastName": "doe",
        "birthPlace": 3,
        "father": 1,
        "mother": 2
    },
    {
        "id": 5,
        "firstName": "emilie",
        "lastName": "doe",
        "birthPlace": 2,
        "father": 1,
        "mother": null
    }
]

Collection's customization

Using query parameters

  • You can filter returned resources by specifying properties name and filter values.
    For example if you want men called john doe, request and response may look like :
// request
GET http://localhost:8000/api/comhon/man?firstName=john&lastName=doe
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {
        "id": 1,
        "firstName": "john",
        "lastName": "doe",
        "birthPlace": 1,
        "father": null,
        "mother": null
    }
]
  • You can filter a property that may have several values (like a IN operator). To do so, you have to suffix property name by []. For example if you want women called emilie or jane, request and response may look like :
// request
GET http://localhost:8000/api/comhon/woman?firstName[]=emilie&firstName[]=jane
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {
        "id": 2,
        "firstName": "jane",
        "lastName": "doe",
        "birthPlace": 2,
        "father": null,
        "mother": null
    },
    {
        "id": 5,
        "firstName": "emilie",
        "lastName": "doe",
        "birthPlace": 2,
        "father": 1,
        "mother": null
    }
]
  • By default, filter is a conjonction, that mean if you have conditions on several properties, conditions are linked by AND operator. But you can set a disjunction (OR) by adding __clause__ query parameter. For example if you want women that have id 2 or firstName emilie, request and response may look like :
// request
GET http://localhost:8000/api/comhon/woman?firstName=emilie&id=2&__clause__=disjunction
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {
        "id": 2,
        "firstName": "jane",
        "lastName": "doe",
        "birthPlace": 2,
        "father": null,
        "mother": null
    },
    {
        "id": 5,
        "firstName": "emilie",
        "lastName": "doe",
        "birthPlace": 2,
        "father": 1,
        "mother": null
    }
]
  • You can order returned resources with query parameter __order__. Order may be ascending (ASC) or descending (DESC) and may be set on several properties. Order value must be a JSON. For example if you want men ordered by birthPlace descending and firstName ascending, request and response may look like :
// request
GET http://localhost:8000/api/comhon/man?__order__=[{"property":"birthPlace", "type":"DESC"},{"property":"firstName", "type":"ASC"}]
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {"id": 4, "firstName": "philippe", "birthPlace": 3,...},
    {"id": 7, "firstName": "jesse", "birthPlace": 2,...},
    {"id": 6, "firstName": "walter", "birthPlace": 2,...},
    {"id": 1, "firstName": "john", "birthPlace": 1,...}
]
  • You can define a range of returned resources with query parameter __range__. it must be used with query parameter __order__. The value of range parameter must look like x-y with x and y natural number (starting from 0) and x <= y. For example if you want the second man to third man, ordered by birthPlace descending and firstName ascending, request and response may look like :
// request
GET http://localhost:8000/api/comhon/man?__range__=1-2&__order__=[{"property":"birthPlace", "type":"DESC"},{"property":"firstName", "type":"ASC"}]
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {"id": 7, "firstName": "jesse", "birthPlace": 2,...},
    {"id": 6, "firstName": "walter", "birthPlace": 2,...}
]
  • You can define returned properties with query parameter __properties__. For example if you want women, and you only want firstName and mother properties, request and response may look like :
// request
GET http://localhost:8000/api/comhon/woman?__properties__[]=firstName&__properties__[]=mother
Accept: application/json

// response
200 OK
Content-Type: application/json

[
    {
        "id": 2,
        "firstName": "jane",
        "mother": null
    },
    {
        "id": 3,
        "firstName": "marie",
        "mother": 2
    },
    {
        "id": 5,
        "firstName": "emilie",
        "mother": null
    }
]

Using body

You can customize request by specifying a request body. You must provide Content-Type header otherwise body is not taken in account. See available media types here. The request format is explained in requester chapter.

HEAD

POST

PUT

DELETE

Media type

There are two available media types.

format media type
XML application/xml
JSON application/json

Clone this wiki locally