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 genapid
Needs 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 exit
The 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.yml
See 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 pipe
is 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 result option). 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: get
If 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 methodURL
Path
: URL pathHost
: URL HostScheme
: URL protocol
Other fields and methods can be used on In
, see the
Request doc.