`aicra` is a lightweight and idiomatic configuration-driven engine for building REST services. It's especially good at helping you write large APIs that remain maintainable as your project grows.
The focus of the project is to allow you to build a fully-featured REST API in an elegant, comfortable and inexpensive way. This is achieved by using a single configuration file to drive the server. This one file describes your entire API: methods, uris, input data, expected output, permissions, etc.
Repetitive tasks are automatically processed by `aicra` based on your configuration, you're left with implementing your handlers (_usually business logic_).
As the configuration file is here to make your life easier, let's take a quick look at what you do not have to do ; or in other words, what does `aicra` automates.
Request data is automatically extracted and validated before it reaches your code. If a request has missing or invalid data an automatic error response is sent.
> Quick note if you thought: "I have JSON, I would have preferred yaml, or even xml !"
>
> I've had a hard time deciding and testing different formats including yaml and xml.
> But as it describes our entire api and is crucial for our server to keep working over updates; xml would have been too verbose with growth and yaml on the other side would have been too difficult to read. Json sits in the right spot for this.
Let's take a quick look at the configuration format !
> if you don't like boring explanations and prefer a working example, see [here](https://git.xdrm.io/go/articles-api/src/master/api.json)
### Services
To begin with, the configuration file defines a list of services. Each one is defined by:
-`method` an HTTP method
-`path` an uri pattern (can contain variables)
-`info` a short description of what it does
-`scope` a list of the required permissions
-`in` a list of input arguments
-`out` a list of output arguments
```json
[
{
"method": "GET",
"path": "/article",
"scope": [["author", "reader"], ["admin"]],
"info": "returns all available articles",
"in": {},
"out": {}
}
]
```
The `scope` is a 2-dimensional list of permissions. The first list means **or**, the second means **and**, it allows for complex permission combinations. The example above can be translated to: this method requires users to have permissions (author **and** reader) **or** (admin)
### Input and output parameters
Input and output parameters share the same format, featuring:
If a parameter is optional you just have to prefix its type with a question mark, by default all parameters are mandatory.
The format of the key of input arguments defines where it comes from:
1.`{param}` is an URI parameter that is extracted from the `"path"`
2.`GET@param` is an URL parameter that is extracted from the [HTTP Query](https://tools.ietf.org/html/rfc3986#section-3.4) syntax.
3.`param` is a body parameter that can be extracted from 3 formats independently:
- _url encoded_: data send in the body following the [HTTP Query](https://tools.ietf.org/html/rfc3986#section-3.4) syntax.
- _multipart_: data send in the body with a dedicated [format](https://tools.ietf.org/html/rfc2388#section-3). This format can be quite heavy but allows to transmit data as well as files.
- _JSON_: data sent in the body as a json object ; The _Content-Type_ header must be `application/json` for it to work.
1.`{id}` is extracted from the end of the URI and is a number compliant with the `int` type checker. It is renamed `ID`, this new name will be sent to the handler.
2.`GET@title` is extracted from the query (_e.g. [http://host/uri?get-var=value](http://host/uri?get-var=value)_). It must be a valid `string` or not given at all (the `?` at the beginning of the type tells that the argument is **optional**) ; it will be named `title`.
3.`content` can be extracted from json, multipart or url-encoded data; it makes no difference and only give clients a choice over the technology to use. If not renamed, the variable will be given to the handler with its original name `content`.
The `api.Err` type automatically maps to HTTP status codes and error descriptions that will be sent to the client as json; clients have to manage the same format for every response.