genapid is an API server using YAML format to describe the API logic.
It can be used to process Webhooks, add some custom commands to a Google Home or as an API broker between several API or IoT services.
Table of Contents
The API is described using pipes of predicates. All predicates in a pipe are evaluated as long as they are true. When a predicate is false, the predicates in the next pipe are evaluated. Some predicates can have side effects, like calling an external API, to perform actual actions.
The examples shows how to receive a Webhook event from Github, mirrors repositories and call an external API or use Google Home to get a voice notification: examples/github/
Control Kodi by voice using a Google Home and receive voice feedback: examples/kodi/
Binary executable for various platforms can be found here:
https://github.com/jsautret/genapid/releases
Just copy genapid or genapid.exe in your PATH.
Docker container is available on Docker Hub:
https://hub.docker.com/repository/docker/jsautret/genapid/general
The configuration file that describes your API must be named api.yml and placed in a directory that you have to mount on /conf volume; port 8080 must be mapped with a local port:
CONF=/etc/genapid # must contain api.yml PORT=9080 docker run --name genapid -d -p $PORT:8080 -v $CONF:/conf jsautret/genapid:latest curl http://localhost:$PORT/test docker logs genapidNeeds go 1.14 or later.
$ go get -u github.com/jsautret/genapid/cmd/genapid Exec will be build here: $GOPATH/bin/genapid.
If you use Ansible, you can adapt the role in ansible/ to deploy genapid behind an Apache server.
$ genapid -h Usage of genapid: -config string Config file (default "api.yml") -loglevel string Log level (default "info") -port int Listening port (default 9110) -version prints current version and exitThe valid log levels are:
- panic
- fatal
- error
- warn
- info
- debug
- trace
The API is described in a YAML file, which is passed to genapid using the -config option.
There is some examples in examples/ directory.
The main structure is a list of predicates. Each predicate is evaluated for each incoming request.
The first element of the top-level list can be init, which contains a list of predicates. The predicates in init are evaluated only once when genapid starts. init can be used to read data from a file and populate the context once for all and not for every request. See the beginning of github.yml for an example.
An include statement can be used everywhere a predicate is allowed. It is replaced by the content of the YAML file when genapid starts.
- include: inc.ymlSee the end of github.yml for an example.
A pipe can be used everywhere a predicate is allowed. Each pipe contains a list of predicates or sub-pipes. The name and result options can be used on pipe (see below for the description of these options).
The result of a pipeis always true, unless result option is set.
The predicates are evaluated for each incoming request received by genapid. When a predicate returns false, the following predicates in the pipe are ignored and the next pipe in the conf is evaluated.
The available predicate types are listed in predicates/. There is also some additional predicates described below.
Each predicates has it own specific parameters described in its documentation.
The following options can be set on predicates:
| Name | Type | Description |
|---|---|---|
name | string | Used for documenting and logs readability only. |
result | boolean | Force the result value of the predicate. |
when | boolean | If false, the predicate evaluation is skipped. |
register | string | Store the results set by the predicate. This data can be accessed in following predicates with the R map. For example, if you set option register: myresult, the data set by the predicate can then be accessed with R.myresult which is a map. The result key will contain the boolean result of the predicate (real one, not the one set with the resultoption). So R.myresult.result can be used to check the result of the predicate. Some predicate may provide additional fields described in their documentation. |
Used to set variables. It takes a list of map as parameters.
The variables can be accessed in predicates with the V map.
Example:
variable: - variable1: value1 - variable2: '= V.variable1 + "_suffix" log: msg: '= "variable2: " + V.variable2 ' # will log "variable2: value1_suffix"Used to set default parameters for predicates. Expressions are evaluated when the predicate is evaluated, not when default is evaluated. Values set by default in a pipe are not available outside that pipe.
Example:
default: http: url: http://domain.com/api method: getIf the value of the parameter of a predicate starts with an = (equal sign), it will be evaluated as a Gval expression. If the evaluation of an expression fails, the predicate returns false.
The Following context is accessible in those expressions:
Map containing data stored using the register option.
Map containing variables set by the variable predicate.
Map containing information about the incoming request received by genapid. It has the following fields:
Method: HTTP methodURLPath: URL pathHost: URL HostScheme: URL protocol
Other fields and methods can be used on In, see the Request doc.