API

View source code

Check out code example

Write the API interface JSON description file, place it in the application apis directory, run yao start When the command starts the service, the engine will generate the RESTFul API interface as defined by the interface description. Yao currently supports RESTFul API to describe MQTT, Socket, WEB Socket API; it is used for data collection and docking, instant messaging, IoT and other types of projects.

Naming conventions

The business interface description file is a JSON text file named with lowercase English letters + .protocol name + .json extension, <name>.<protocol>.json;

Folder (relative to business interface root directory)File nameInterface nameAPI type
/name.http.jsonnamehttp RESTFul API
/groupname.http.jsongroup.namehttp RESTFul API
/group1/group2name.http.jsongroup1.group2.namehttp RESTFul API
/name.mqtt.jsonnamemqtt MQTT API
/groupname.mqtt.jsongroup.namemqtt MQTT API
/group1/group2name.mqtt.jsongroup1.group2.namemqtt MQTT API
/name.sock.jsonnamesock Socket API
/groupname.sock.jsongroup.namesock Socket API
/group1/group2name.sock.jsongroup1.group2.namesock Socket API
/name.ws.jsonnamews WEB Socket API
/groupname.ws.jsongroup.namews WEB Socket API
/group1/group2name.ws.jsongroup1.group2.namews WEB Socket API

Each protocol specification document

Protocol NameDocument Address
httpRESTFul API
mqttMQTT API Not yet implemented
sockSocket API (in beta)
wsWEB Socket API (in beta)

An interface (API) document of the http protocol, which can define a set of APIs, and can bind a process (process) to each API, and the system automatically calls the process and returns the result of the process call;

FieldsTypeDescriptionRequired Fields
nameStringAPI rendering name, used for development platform renderingyes
versionStringVersion number, used for dependency check and development platform renderingyes
descriptionStringAPI introduction, used for development platform renderingno
groupStringAPI group name, used as the API route prefix directory when accessing. /api/<group>/<path>yes
guardStringAPI global middleware, multiple separated by ",". Unless otherwise specified, all APIs in the group will use global middlewareno
pathsArray\<Object Path>API list. Check the Object Path data structure for detailsyes

Object Path data structure

The API will be accessed through the route /api/<group>/<path>, the request succeeds and responds to the status code, Content-Type and the return value of the process (process) defined in out, and the request fails and responds to the exception status code and error messages in JSON format [see exception specification](#Exception specification).

FieldsTypeDescriptionRequired Fields
pathStringAPI route name. The complete routing address is /api/<group>/<path>, variables are declared with :, such as /api/user/find/:id, you can use $param.id to access routing request parametersyes
methodStringThe request type. Permitted values ​​GET, POST, PUT, DELETE, HEAD, OPTIONS, Any. where Any will respond to any type of requestyes
guardStringAPI middleware. If not set, the global middleware is used by default. If you don't want to use global middleware, set the value to - .No
processStringInvoke process processyes
inArray\<String>Request argument list, which will be used as input arguments (args) to process. Can refer to incoming parameters, can be an empty array [View input parameters](#input parameters)yes
outObject OutRequest response result definition. See the Object Out data structure for detailsyes
errObject OutCustomize the response when the call fails. Not yet implementedNo

Object Out data structure

FieldsTypeDescriptionRequired Fields
statusintegerRequest response status codeYes
typeStringRequest response Content TypeYes
headersArray\<String>Request response headers Not yet implementedNo

Input parameters

The parameter list defined in in will be used as input parameters to the process. Supports the use of :param , :payload , $param.field name and other variables to bind request parameters.

Numerical value

ValueDescription
"'String'"String format value, escape single quotes with \
"Number"Numeric format value

variables

variabletypedescription
":body"stringRequest Body
":fullpath"stringroute full path
":payload"[key:String]:AnyIf Request Content-Type is application/json , treat Reqest Body as JSON. Return the decoded Key-Value Object
":query"[key:String]:AnyURL-encoded Query String parsed value
":form"[key:String]:AnyPOST form
":query-param"Object QueryParamParse URL-encoded Query String, return QueryParam View data structure (../../model#3-query-parameter-queryparam)
"$form.FieldName"StringPOST form field value
"$param.FieldName"StringRoute variable value
"$query.FieldName"StringURL-encoded Query String Field value
"$payload.field name"Anypayload field value, supports multi-level access. Such as $payload.user.name , $payload.manus.0.name
"$session.FieldName"AnySession The number of session fields, supports multi-level access. Such as $session.user.name , $session.manus.0.name value
"$file.FieldName"Object FileUpload temporary file structure

Object File data structure

FieldTypeDescription
nameStringfile name
tempfileStringtemporary file address
sizeIntegerfile size
header[key:String]:Array\<String>MIME-style header mapping
URL Query String and QueryParam comparison table
Query StringQueryParamDescription
select=field1,field2{"select":["field1","field2"]}select field
with=rel1,rel2{"withs":{"rel1":{}, "rel2":{}}}Association
rel1.select=field1,field2{"withs":{"rel1":{"select":["field1", "field2"]}}}associated model selection field. The specification is association .select
where.status.eq=enabled{"wheres":[{"column":"status", "op":"eq", "method":"where", "value":"enabled"}] }Where query condition. The specification is where. field name. match relation
where.mother.friends.status.eq=enabled{"wheres":[{"rel":"user_mother_friends","column":"status", "op":"eq", "method":"where", "value":"enabled"}]}Specify the associated model field specification as where.relationship Name.Associated ModelName.FieldName.Match relation
group.types.where.type.eq=admin&group.types.orwhere.type.eq=staff{"wheres":[{"wheres":[{"column":"type", "op":" eq", "method":"where", "value":"admin"}]},{"column":"type", "op":"eq", "method":"orwhere", "value" :"staff"}]}]}Where group query, generally used for orwhere. The specification is group.group name.where.field name.match relation
order=id.desc,name{"orders":[{"column":"id","option":"desc"}, {"column":"name"}]}Order condition. The specification is field name. Sorting method Multiple are separated by ","

Exception Specification

{
"code": 500,
"message": "Data with ID=12 does not exist",
"context": {
"field": "id"
}
}
FieldTypeDescription
codeIntegerError code
messageStringError description
contextAnyexception context information

HTTP Response Status Code

The returned status is consistent with the error code. For example, if the HTTP Response status code is 400~599, it will be regarded as a program processing exception.

Error code definition

The meaning of the error code is basically the same as the meaning of the HTTP protocol status code, which is convenient for RESTFul API writing, unified exception handling and engineers to understand the meaning of the error code.

Error codeApplicable scenarios
400~499The program failed to run due to incorrect input data
500~599The program fails due to insufficient server resources or abnormal program errors
400The program failed to run because the input data does not meet the requirements. Specific non-conforming data fields should be described in the contextual data.
401The program failed to run because you are not logged in.
403The program failed to run due to insufficient access rights. Specific permission requirement information should be described in the context data.
404The program failed to run because the query resource does not exist. The resource name and data ID should be described in the context data.
413The program failed to run because the input data was out of bounds.
500The program failed to run due to a server exception. Specific error data should be described in the context data. For example: File writing failed due to insufficient disk space.
503The server is temporarily unreachable, causing the program to fail. For example: MySQL server has gone away!
504Program failed due to connection timeout. For example: MySQL server connect timeout!

Using guard

Using gurad in the request api is similar to using middleware to filter requests and intercept some requests that do not meet the conditions. When defining the api, specify the handler used by the guard field.

Use the system's own guard bearer-jwt

Specifies that the entire grouping api should authenticate the login

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"guard": "bearer-jwt",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Specifying an interface alone requires authentication and login

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"guard": "bearer-jwt",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Example:

Write an interface description file apis/select.http.json, specify the interface path, request method and bound handler, and place it in the apis directory of the application.

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"guard": "-",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Create a new flows/category.flow.json file:

{
"label": "Category Tree",
"version": "1.0.0",
"description": "Category Tree",
"nodes": [
{
"name": "Category",
"engine": "xiang",
"query": {
"select": ["id", "name", "name as label", "id as value", "parent_id"],
"wheres": [{ ":deleted_at": "deleted", "=": null }],
"from": "category",
"limit": 1000
}
},
{
"name": "Category Tree",
"process": "xiang.helper.ArrayTree",
"args": ["{{$res.category}}", { "parent": "parent_id" }]
}
],
"output": "{{$res.category tree}}"
}

call 127.0.0.1/api/select/category

API

View source code

Check out code example

Write the API interface JSON description file, place it in the application apis directory, run yao start When the command starts the service, the engine will generate the RESTFul API interface as defined by the interface description. Yao currently supports RESTFul API to describe MQTT, Socket, WEB Socket API; it is used for data collection and docking, instant messaging, IoT and other types of projects.

Naming conventions

The business interface description file is a JSON text file named with lowercase English letters + .protocol name + .json extension, <name>.<protocol>.json;

Folder (relative to business interface root directory)File nameInterface nameAPI type
/name.http.jsonnamehttp RESTFul API
/groupname.http.jsongroup.namehttp RESTFul API
/group1/group2name.http.jsongroup1.group2.namehttp RESTFul API
/name.mqtt.jsonnamemqtt MQTT API
/groupname.mqtt.jsongroup.namemqtt MQTT API
/group1/group2name.mqtt.jsongroup1.group2.namemqtt MQTT API
/name.sock.jsonnamesock Socket API
/groupname.sock.jsongroup.namesock Socket API
/group1/group2name.sock.jsongroup1.group2.namesock Socket API
/name.ws.jsonnamews WEB Socket API
/groupname.ws.jsongroup.namews WEB Socket API
/group1/group2name.ws.jsongroup1.group2.namews WEB Socket API

Each protocol specification document

Protocol NameDocument Address
httpRESTFul API
mqttMQTT API Not yet implemented
sockSocket API (in beta)
wsWEB Socket API (in beta)

An interface (API) document of the http protocol, which can define a set of APIs, and can bind a process (process) to each API, and the system automatically calls the process and returns the result of the process call;

FieldsTypeDescriptionRequired Fields
nameStringAPI rendering name, used for development platform renderingyes
versionStringVersion number, used for dependency check and development platform renderingyes
descriptionStringAPI introduction, used for development platform renderingno
groupStringAPI group name, used as the API route prefix directory when accessing. /api/<group>/<path>yes
guardStringAPI global middleware, multiple separated by ",". Unless otherwise specified, all APIs in the group will use global middlewareno
pathsArray\<Object Path>API list. Check the Object Path data structure for detailsyes

Object Path data structure

The API will be accessed through the route /api/<group>/<path>, the request succeeds and responds to the status code, Content-Type and the return value of the process (process) defined in out, and the request fails and responds to the exception status code and error messages in JSON format [see exception specification](#Exception specification).

FieldsTypeDescriptionRequired Fields
pathStringAPI route name. The complete routing address is /api/<group>/<path>, variables are declared with :, such as /api/user/find/:id, you can use $param.id to access routing request parametersyes
methodStringThe request type. Permitted values ​​GET, POST, PUT, DELETE, HEAD, OPTIONS, Any. where Any will respond to any type of requestyes
guardStringAPI middleware. If not set, the global middleware is used by default. If you don't want to use global middleware, set the value to - .No
processStringInvoke process processyes
inArray\<String>Request argument list, which will be used as input arguments (args) to process. Can refer to incoming parameters, can be an empty array [View input parameters](#input parameters)yes
outObject OutRequest response result definition. See the Object Out data structure for detailsyes
errObject OutCustomize the response when the call fails. Not yet implementedNo

Object Out data structure

FieldsTypeDescriptionRequired Fields
statusintegerRequest response status codeYes
typeStringRequest response Content TypeYes
headersArray\<String>Request response headers Not yet implementedNo

Input parameters

The parameter list defined in in will be used as input parameters to the process. Supports the use of :param , :payload , $param.field name and other variables to bind request parameters.

Numerical value

ValueDescription
"'String'"String format value, escape single quotes with \
"Number"Numeric format value

variables

variabletypedescription
":body"stringRequest Body
":fullpath"stringroute full path
":payload"[key:String]:AnyIf Request Content-Type is application/json , treat Reqest Body as JSON. Return the decoded Key-Value Object
":query"[key:String]:AnyURL-encoded Query String parsed value
":form"[key:String]:AnyPOST form
":query-param"Object QueryParamParse URL-encoded Query String, return QueryParam View data structure (../../model#3-query-parameter-queryparam)
"$form.FieldName"StringPOST form field value
"$param.FieldName"StringRoute variable value
"$query.FieldName"StringURL-encoded Query String Field value
"$payload.field name"Anypayload field value, supports multi-level access. Such as $payload.user.name , $payload.manus.0.name
"$session.FieldName"AnySession The number of session fields, supports multi-level access. Such as $session.user.name , $session.manus.0.name value
"$file.FieldName"Object FileUpload temporary file structure

Object File data structure

FieldTypeDescription
nameStringfile name
tempfileStringtemporary file address
sizeIntegerfile size
header[key:String]:Array\<String>MIME-style header mapping
URL Query String and QueryParam comparison table
Query StringQueryParamDescription
select=field1,field2{"select":["field1","field2"]}select field
with=rel1,rel2{"withs":{"rel1":{}, "rel2":{}}}Association
rel1.select=field1,field2{"withs":{"rel1":{"select":["field1", "field2"]}}}associated model selection field. The specification is association .select
where.status.eq=enabled{"wheres":[{"column":"status", "op":"eq", "method":"where", "value":"enabled"}] }Where query condition. The specification is where. field name. match relation
where.mother.friends.status.eq=enabled{"wheres":[{"rel":"user_mother_friends","column":"status", "op":"eq", "method":"where", "value":"enabled"}]}Specify the associated model field specification as where.relationship Name.Associated ModelName.FieldName.Match relation
group.types.where.type.eq=admin&group.types.orwhere.type.eq=staff{"wheres":[{"wheres":[{"column":"type", "op":" eq", "method":"where", "value":"admin"}]},{"column":"type", "op":"eq", "method":"orwhere", "value" :"staff"}]}]}Where group query, generally used for orwhere. The specification is group.group name.where.field name.match relation
order=id.desc,name{"orders":[{"column":"id","option":"desc"}, {"column":"name"}]}Order condition. The specification is field name. Sorting method Multiple are separated by ","

Exception Specification

{
"code": 500,
"message": "Data with ID=12 does not exist",
"context": {
"field": "id"
}
}
FieldTypeDescription
codeIntegerError code
messageStringError description
contextAnyexception context information

HTTP Response Status Code

The returned status is consistent with the error code. For example, if the HTTP Response status code is 400~599, it will be regarded as a program processing exception.

Error code definition

The meaning of the error code is basically the same as the meaning of the HTTP protocol status code, which is convenient for RESTFul API writing, unified exception handling and engineers to understand the meaning of the error code.

Error codeApplicable scenarios
400~499The program failed to run due to incorrect input data
500~599The program fails due to insufficient server resources or abnormal program errors
400The program failed to run because the input data does not meet the requirements. Specific non-conforming data fields should be described in the contextual data.
401The program failed to run because you are not logged in.
403The program failed to run due to insufficient access rights. Specific permission requirement information should be described in the context data.
404The program failed to run because the query resource does not exist. The resource name and data ID should be described in the context data.
413The program failed to run because the input data was out of bounds.
500The program failed to run due to a server exception. Specific error data should be described in the context data. For example: File writing failed due to insufficient disk space.
503The server is temporarily unreachable, causing the program to fail. For example: MySQL server has gone away!
504Program failed due to connection timeout. For example: MySQL server connect timeout!

Using guard

Using gurad in the request api is similar to using middleware to filter requests and intercept some requests that do not meet the conditions. When defining the api, specify the handler used by the guard field.

Use the system's own guard bearer-jwt

Specifies that the entire grouping api should authenticate the login

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"guard": "bearer-jwt",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Specifying an interface alone requires authentication and login

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"guard": "bearer-jwt",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Example:

Write an interface description file apis/select.http.json, specify the interface path, request method and bound handler, and place it in the apis directory of the application.

{
"name": "Drop down search",
"version": "1.0.0",
"description": "Drop down search",
"guard": "-",
"group": "select",
"paths": [
{
"path": "/category",
"method": "GET",
"process": "flows.category",
"in": [],
"out": {
"status": 200,
"type": "application/json"
}
}
]
}

Create a new flows/category.flow.json file:

{
"label": "Category Tree",
"version": "1.0.0",
"description": "Category Tree",
"nodes": [
{
"name": "Category",
"engine": "xiang",
"query": {
"select": ["id", "name", "name as label", "id as value", "parent_id"],
"wheres": [{ ":deleted_at": "deleted", "=": null }],
"from": "category",
"limit": 1000
}
},
{
"name": "Category Tree",
"process": "xiang.helper.ArrayTree",
"args": ["{{$res.category}}", { "parent": "parent_id" }]
}
],
"output": "{{$res.category tree}}"
}

call 127.0.0.1/api/select/category