xdrm-framework/notice/api/3.0.md

13 KiB

module: api
version: 3.0
requires:
  - http:  1.0
  - error: 2.0

Links

I. Overview

II. Usage

III. Configuration

IV. Implementation

V. Class documentation

I. Overview

1 Introduction & features

The api package (v2.2) allows you to easily create and manage an API. It could be used for an HTTP API (REST, or other kind), or you can use it as an internal core for your system.

The aim of this package is to make your life easier working with APIs or internal delegation. The only things you have to do is to implement your processes and edit the configuration, the package will do the rest.

Things you have to do :

  • implement your processes (obviously)
  • implement your authentication system (cf. AuthSystem)
  • edit the configuration file (cf. configuration)

Things you don't have to do :

  • input type check (cf. Checker)
  • API multiple permission management
  • optional or required inputs
  • before and after scripts
  • catch both in-URL and multipart/form-data input

2 Basic knowledge

The API is based over a 2-level delegation structure :

  1. module which is a set of methods
  2. method which have input, output, permissions, and is bound to a function

So each of your functionalities must have a method name and be inside a module.

Example:

  • the module article contains methods:
    • read with argument article_id (to identify the wanted article)
    • write with arguments title and body (data to write into the new created article)
    • edit with arguments article_id and body (to identify and replace the body)
    • delete with argument article_id (to identify which article to delete)

If you want to delete the article of id 52, you must request article/delete passing article_id=52.

II. Usage

1 Setup

In order to make the API work, you have to :

  1. Edit the configuration file according to your needs (cf. configuration)
  2. Implement the Authentication System to manage permissions (cf. AuthSystem)
  3. Implement the code of the methods according to the configuration

2 Php requirements

1) include the autoloader file

<?php require_once '../autoloader.php';

2) load useful classes

// for API use
use \api\core\Request;
use \api\core\Response;

// for error handling
use \error\core\Err;

3 From php internally

1) create a request

// creates a request for the module {module} and its method {method} with params
$request = new Request('{module}/{method}', [
	'param1' => 10,
	'param2' => 'somevalue'
]);

2) catch possible errors (optional)

// if error is not Err::Success
if( $request->error->get() !== Err::Success )
	'do something';

3) execute the request and catch response

$response = $request->dispatch();

4) catch response errors (optional)

// if error is not Err::Success
if( $response->error->get() !== Err::Success )
	'do something';

5) catch response output

// fetch all outputs
$output = $response->getAll();

// fetch specific output
$specific = $response->get('someOutputName');

4 From HTTP requests

In order to setup an automatic bound from HTTP requests to API directly, you must use a router.

1) Format url so it must begin with /{module}/{method}

// let's suppose the url is `/api/{module}/{method}`
$url = '/api/somemodule/somemethod/1/2/';
$uri = substr($url, strlen('/api'));
// $uri = /somemodule/somemethod/1/2/

2) give the url to the HTTP manager

// create request from HTTP data
$request = Request::remote($url);

// execute request and catch response
// note that request errors will propagate through response
$response = $request->dispatch();

// return response as HTTP body
die( $response->serialize() );

Then can handle various kinds of URL :

  • request and parameters can be in URL (separated by /)
  • request and parameters can be in multipart/form-data or x-www-form-urlencoded
  • request and parameters of both URL, post data, and form-data are caught

The following examples can work :

  1. http://www.host.com/{module}/{method}/
"post-data": {
	"param1": "{value1}",
	"param2": "{value2}"
}
  1. http://www.host.com/{module}/{method}/{param1}/{param2}
"post-data": {}
  1. http://www.host.com/apiOrParentUrl/
"post-data": {
	"module": "{module}",
	"method": "{method}",
	"param1": "{value1}",
	"param2": "{value2}"
}
  1. http://www.host.com/apiOrParentUrl/{value1}/{value2}
"post-data": {
	"module": "{module}",
	"method": "{method}",
}

III. Configuration

{

	"{module_name}": {

		"{http_method}::{method_name}": {
			"description": "{method_description}",
			"permissions": ["{method_perm}"],
			"options": { "download": "{is_downloadable}" },
			"parameters": {
				"{name_param}": { "description": "{desc_param}", "type": "{type_param}", "optional": "{is_optional}" }
			},
			"output": {
				"{name_output}": { "description": "{desc_output}", "type": "{type_output}" }
			}
		}

	}
}
variable description exemple
{module_name} alphanumeric module name "publications"
{http_method} uppercase HTTP method "POST"
{method_name} alphanumeric method name "article"
{method_description} textual description "Returns a specific article"
{method_perm} permission array ["poster", "admin", "user"]
{is_downloadable} If you want this method to return a file true, false
{name_param} Your param's name * "id_article"
{desc_param} Your param's description "Wanted article's id"
{type_param} Your param's type (cf. Checker) "Wanted article's type"
{is_optional} Whether to make your param required true, false
{name_output} Your output's name "article"
{desc_output} Your output's description "Article content"

* If you want URL (GET) parameters, the {param_name} must be URL_0, URL_1 and so on according to the index wanted in the URL.

api/module/method/URL_0/URL_1/URL_2/

IV. Implementation

1 Permissions : AuthSystem

In order to implement your Authentification System you have to implement the interface AuthSystem located in /build/api/core/AuthSystem.

You must register your custom authentification system before each api call with :

// let's suppose your auth system class is "AuthSystemDefault"
\api\core\Request::setAuthSystem(new AuthSystemDefault);

2 Modules & methods

Module implementation

Each module's implementation is represented as a file so as a class located in /build/api/module/. In order for the autoloader to work, you must name the file the same name as the class.

Method implementation

Each method is represented as a method in its module's class.

Input arguments

Arguments are passed to the method as a single argument which an associative array according to the documentation.

Notes:

  • Optional parameters if not given are set to null
  • parameters of type FILE are given by reference but the use is the same as normal parameters
  • URL parameters are called URL_0, URL_1 and so on according to their order.

Ouput required

You must return an associative array containing at least the field error containing an instance of /api/core/Error, then you can add whatever you want to return in the array.

If you don't return the 'error' field, by default it is set to new Error(Err::Success).

V. Class documentation

1 Request

Attributes

The attribute error will contain the current Error instance.

<?php
	public $error;

Methods

Creates a new Request object, you must give it a path following the pattern "module/method", the params must be an associative array. Note that the path can be inside the $params variable.

It checks missing params and each needed params' type according to the Checker implementation (cf. Checker). It also checks the permissions you have according to the AuthSystem implementation (cf. AuthSystem).

<?php
	public function __construct(String $path, Array $params) : Request;

Creates a new Request object but from the URL. It will seek for the path in the URL, then in the data. (it will call itself the __construct() method).

<?php
	public static function remote(String $url, Array $data) : Request;

Registers the AuthSystem you want, must be done before any construction.

<?php
	public static function setAuthSystem(Request $instance) : bool;

Executes the current Request object and returns a Response object.

<?php
	public function dispatch() : Response;

Same as dispatch() but manages the download option (cf. Configuration). It will use 2 of the parameters you must return on success : body, and headers. The first one must contain the content of the file to create, the second the headers in an associative array.

The call will become the file itself.

Note: If the HTTP_X_REQUESTED_WITH header is present, it will create the downloadable file as /tmp/download_{some_hash} and return a normal Response object with the field link containing the file absolute path.

<?php
	public function download() : null;
	public function download() : Response; // if called by Ajax

2 Response

Attributes

The attribute error will contain the current Error instance.

<?php
	public $error;

Methods

Returns an associative array containing the whole response data (excluding the error).

<?php
	public function getAll() : Array;

Returns only the field from the response data (if it exists).

<?php
	public function get(String $key) : mixed; // on success
	public function get(String $key) : null;  // on error

Sets the HTTP_CODE according to the Error argument, also it sets the header for application/json.

It can be used for simple API response, it will add the "error" and "ErrorDescription" fields to the data and set the headers so you can display the result of the API call.

<?php
	public function serialize() : String;

4 Checker

Checker checks the input values according to the type given in the configuration.

The default types below are available in the default package. To add a new type, just open the file /build/api/Checker.php and add an entry in the switch statement.

Default types

Type Example Description
mixed [9,"a"], "a" Any content (can be simple or complex)
id 10, "23" Positive integer number between 0 and 2147483647
numeric -10.2, "23" Any number, null and the string "null"
text "Hello!" String that can be of any length (even empty)
hash "4612473aa81f93a878674f9ebffa8d63a1b51ea28dcdcdb1e89eb512aae9b77e" String with a length of 40 or 64, containing only hexadecimal characters
alphanumeric "abc029.-sd9" String containing only alphanumeric, ___, -, and . characters
letters "abc -sd" String containing only letters, -, and space characters
mail "a.b@c.def" Valid email address
number 0102030405 Phone number, following formats allowed : 06, +336, +33 6
array [1, 3] Non-empty array
object works only within php Non-empty object
boolean true, false Boolean
varchar(a,b) "Hello!" String with a length between a and b (included)
varchar(a,b,c) "abc" String with a length between a and b (included) and matching the c type

Complex type : chainable array

Type Sub-Type Description
array<a> a Array containing only entries matching the type a

Note: It is possible to chain array type as many as needed. Ex.: array<array<id>> - Will match array only containing arrays that only contains id entries.

5 Advanced

Before and After scripts

Each time a method is called, the api creates an instance from the class, and after the execution, the class is destroyed. So you can implement the methods __construct and __destruct to add before and after scripts.