The `api` package (v3.0) allows you to easily create and manage an API for your applications. It can be used as an HTTP API (REST, or other kind), and 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 and internal delegation. The only things you have to do is to implement your processes and write the configuration, the package will do the rest.
The api is made of paths that binds to a *php class*, each `path` can manage multiple **HTTP METHODS** each will correspond to a *method* of the bound class.
For instance the 4 methods directly inside `uri1` will be triggered when the calling URI is `/uri1`, the ones directly inside `uri2` will be triggered when calling `/uri1/uri2` and so on..
You can also set full paths if you don't need transitional methods, for instance the path `uri5/uri6/uri7` will be triggered by the url `/uri5/uri6/uri7`.
The *name* field must be a **string** containing variable name that will be asked for the caller.
Note that you can set any string for **body parameters**, but **GET parameters** must be named `URL#`, where `#` is the index within the URI, beginning with 0.
#### parameter.description
The *description* field must be a **string** containing the human-readable description of what the parameter is or must be.
#### parameter.checker_type
The *checker_type* field must be a **string** corresponding to a `\api\core\Checker` type that will be checked before calling the implementation.
The *is_optional* field must be a **boolean** set to `true` if the parameter can be ommited. By default, the field is set to `false` so each parameter is required.
The *rename* field must be a **string** corresponding to the *variable name* given to the implementation. It is useful for **GET parameters** because they need to be called `URL#`, where `#` is the position in the URI. (cf. [paramter.name](#parametername)))
The *default_value* field must be of any type according to the *checker_type* field, it will be used only for **optional** parameters when ommited by the caller
The *output_format* field must have the same format as `method.parameters` but will only be used to generate a documentation or to tell other developers what the method returns if no error occurs.
The *options* field must be an **object** containing the available options.
The only option available for now is:
```json
"download": true
```
Your implementation must return 2 fields:
-`body` a string containing the file body
-`headers` an array containing as an associative array file headers
If the API is called with HTTP directly, it will not print the **json** response (only on error), but will instead directly return the created file.
*AJAX:* If called with ajax, you must give the header `HTTP_X_REQUESTED_WITH` set to `XMLHttpRequest`. In that case only, it will return a normal JSON response with the field `link` containing the link to call for downloading the created file. **You must take care of deleting not used files** - there is no such mechanism.
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**.
*Specific*: For the root (`/`) path, it will trigger the class `\api\module\root`, so you have to create the file `/build/api/module/root.php`. (cf. [configuration format](#1---configuration-format))
* Optional parameters if not given are set to their default value (cf. [parameter.optional](#parameteris_optional), [parameter.default_value](#parameterdefault_value))
* parameters of type `FILE` are given by reference but the use is the same as normal parameters (cf. [complex types](#2---complex-types))
* URI parameters are called `URL0`, `URL1` and so on according to their order if no `rename` set in the configuration. (cf: [parameter.name](#parametername), [parameter.rename](#parameterrename))
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.
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.
You can request the API for information about the current URI by using the `OPTIONS` HTTP method.
====
# **I.** Simple request
## **1** - URL
### format
The `uri` format is as defined: `{base}/{path}/{GET_parameters}`, where
-`{base}` is the server's *API* base uri (ex: `https://example.com/api/v1` or `https://api.exampl.com`)
-`{path}` is the effective path you want to access (ex: `article/author`)
-`{GET_parameters}` is a set of slash-separated values (ex: `val0/val1/val2//val4`)
*Note:* GET parameters are not used as usual (`?var1=val1&var2=val2...`), instead the position in the URL gives them an implicit name which is `URL#`, where `#` is the index in the uri (beginning with 0).
### example 1
If you want to edit an article with the server's REST API, it could be defined as following:
```yaml
http: PUT
path: article/{id_article}
input:
body: new content of the article
output:
updated: the updated article data
```
Let's take the example where you want to update the article which id is **23** and set its body to "**blabla new content**"
`HTTP REQUEST`
```
PUT article/23 HTTP/1.0
body=blabla+new+content
```
`HTTP RESPONSE`
```
HTTP/1.0 200 OK
Content-Type: application/json
{
"error": 0,
"ErrorDescription": "all right",
"updated": {
"id_article": 23,
"title": "article 23",
"body": "blabla new content"
}
}
```
### example 2
If you want to get a specific article line, the request could be defined as following
```yaml
http: GET
path: article/line/{id_article}/{no_line}
input: -
output:
articles: the list of matching lines
```
Let's take the example where you want to get **all articles** because `id_article` is set to optional, but you only want the first line of each so you have to give only the second parameter set to `1` (first line).
*Solution:* The position in the `uri` where `id_article` must be, have to be left empty: it will result of 2 slashes (`//`).