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.
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 name | Interface name | API type |
---|---|---|---|
/ | name.http.json | name | http RESTFul API |
/group | name.http.json | group.name | http RESTFul API |
/group1/group2 | name.http.json | group1.group2.name | http RESTFul API |
/ | name.mqtt.json | name | mqtt MQTT API |
/group | name.mqtt.json | group.name | mqtt MQTT API |
/group1/group2 | name.mqtt.json | group1.group2.name | mqtt MQTT API |
/ | name.sock.json | name | sock Socket API |
/group | name.sock.json | group.name | sock Socket API |
/group1/group2 | name.sock.json | group1.group2.name | sock Socket API |
/ | name.ws.json | name | ws WEB Socket API |
/group | name.ws.json | group.name | ws WEB Socket API |
/group1/group2 | name.ws.json | group1.group2.name | ws WEB Socket API |
Protocol Name | Document Address |
---|---|
http | RESTFul API |
mqtt | MQTT API Not yet implemented |
sock | Socket API (in beta) |
ws | WEB 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;
Fields | Type | Description | Required Fields |
---|---|---|---|
name | String | API rendering name, used for development platform rendering | yes |
version | String | Version number, used for dependency check and development platform rendering | yes |
description | String | API introduction, used for development platform rendering | no |
group | String | API group name, used as the API route prefix directory when accessing. /api/<group>/<path> | yes |
guard | String | API global middleware, multiple separated by ",". Unless otherwise specified, all APIs in the group will use global middleware | no |
paths | Array\<Object Path> | API list. Check the Object Path data structure for details | yes |
Object Path
data structureThe 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).
Fields | Type | Description | Required Fields |
---|---|---|---|
path | String | API 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 parameters | yes |
method | String | The request type. Permitted values GET , POST , PUT , DELETE , HEAD , OPTIONS , Any . where Any will respond to any type of request | yes |
guard | String | API 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 |
process | String | Invoke process process | yes |
in | Array\<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 |
out | Object Out | Request response result definition. See the Object Out data structure for details | yes |
err | Object Out | Customize the response when the call fails. Not yet implemented | No |
Object Out
data structureFields | Type | Description | Required Fields |
---|---|---|---|
status | integer | Request response status code | Yes |
type | String | Request response Content Type | Yes |
headers | Array\<String> | Request response headers Not yet implemented | No |
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.
Value | Description |
---|---|
"'String'" | String format value, escape single quotes with \ |
"Number" | Numeric format value |
variable | type | description |
---|---|---|
":body" | string | Request Body |
":fullpath" | string | route full path |
":payload" | [key:String]:Any | If Request Content-Type is application/json , treat Reqest Body as JSON. Return the decoded Key-Value Object |
":query" | [key:String]:Any | URL-encoded Query String parsed value |
":form" | [key:String]:Any | POST form |
":query-param" | Object QueryParam | Parse URL-encoded Query String, return QueryParam View data structure (../../model#3-query-parameter-queryparam) |
"$form.FieldName" | String | POST form field value |
"$param.FieldName" | String | Route variable value |
"$query.FieldName" | String | URL-encoded Query String Field value |
"$payload.field name" | Any | payload field value, supports multi-level access. Such as $payload.user.name , $payload.manus.0.name |
"$session.FieldName" | Any | Session The number of session fields, supports multi-level access. Such as $session.user.name , $session.manus.0.name value |
"$file.FieldName" | Object File | Upload temporary file structure |
Object File
data structure
Field | Type | Description |
---|---|---|
name | String | file name |
tempfile | String | temporary file address |
size | Integer | file size |
header | [key:String]:Array\<String> | MIME-style header mapping |
Query String | QueryParam | Description |
---|---|---|
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 "," |
{"code": 500,"message": "Data with ID=12 does not exist","context": {"field": "id"}}
Field | Type | Description |
---|---|---|
code | Integer | Error code |
message | String | Error description |
context | Any | exception context information |
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.
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 code | Applicable scenarios | |
---|---|---|
400~499 | The program failed to run due to incorrect input data | |
500~599 | The program fails due to insufficient server resources or abnormal program errors | |
400 | The 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. | |
401 | The program failed to run because you are not logged in. | |
403 | The program failed to run due to insufficient access rights. Specific permission requirement information should be described in the context data. | |
404 | The program failed to run because the query resource does not exist. The resource name and data ID should be described in the context data. | |
413 | The program failed to run because the input data was out of bounds. | |
500 | The 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. | |
503 | The server is temporarily unreachable, causing the program to fail. For example: MySQL server has gone away! | |
504 | Program failed due to connection timeout. For example: MySQL server connect timeout! |
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.
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"}}]}
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
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.
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 name | Interface name | API type |
---|---|---|---|
/ | name.http.json | name | http RESTFul API |
/group | name.http.json | group.name | http RESTFul API |
/group1/group2 | name.http.json | group1.group2.name | http RESTFul API |
/ | name.mqtt.json | name | mqtt MQTT API |
/group | name.mqtt.json | group.name | mqtt MQTT API |
/group1/group2 | name.mqtt.json | group1.group2.name | mqtt MQTT API |
/ | name.sock.json | name | sock Socket API |
/group | name.sock.json | group.name | sock Socket API |
/group1/group2 | name.sock.json | group1.group2.name | sock Socket API |
/ | name.ws.json | name | ws WEB Socket API |
/group | name.ws.json | group.name | ws WEB Socket API |
/group1/group2 | name.ws.json | group1.group2.name | ws WEB Socket API |
Protocol Name | Document Address |
---|---|
http | RESTFul API |
mqtt | MQTT API Not yet implemented |
sock | Socket API (in beta) |
ws | WEB 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;
Fields | Type | Description | Required Fields |
---|---|---|---|
name | String | API rendering name, used for development platform rendering | yes |
version | String | Version number, used for dependency check and development platform rendering | yes |
description | String | API introduction, used for development platform rendering | no |
group | String | API group name, used as the API route prefix directory when accessing. /api/<group>/<path> | yes |
guard | String | API global middleware, multiple separated by ",". Unless otherwise specified, all APIs in the group will use global middleware | no |
paths | Array\<Object Path> | API list. Check the Object Path data structure for details | yes |
Object Path
data structureThe 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).
Fields | Type | Description | Required Fields |
---|---|---|---|
path | String | API 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 parameters | yes |
method | String | The request type. Permitted values GET , POST , PUT , DELETE , HEAD , OPTIONS , Any . where Any will respond to any type of request | yes |
guard | String | API 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 |
process | String | Invoke process process | yes |
in | Array\<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 |
out | Object Out | Request response result definition. See the Object Out data structure for details | yes |
err | Object Out | Customize the response when the call fails. Not yet implemented | No |
Object Out
data structureFields | Type | Description | Required Fields |
---|---|---|---|
status | integer | Request response status code | Yes |
type | String | Request response Content Type | Yes |
headers | Array\<String> | Request response headers Not yet implemented | No |
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.
Value | Description |
---|---|
"'String'" | String format value, escape single quotes with \ |
"Number" | Numeric format value |
variable | type | description |
---|---|---|
":body" | string | Request Body |
":fullpath" | string | route full path |
":payload" | [key:String]:Any | If Request Content-Type is application/json , treat Reqest Body as JSON. Return the decoded Key-Value Object |
":query" | [key:String]:Any | URL-encoded Query String parsed value |
":form" | [key:String]:Any | POST form |
":query-param" | Object QueryParam | Parse URL-encoded Query String, return QueryParam View data structure (../../model#3-query-parameter-queryparam) |
"$form.FieldName" | String | POST form field value |
"$param.FieldName" | String | Route variable value |
"$query.FieldName" | String | URL-encoded Query String Field value |
"$payload.field name" | Any | payload field value, supports multi-level access. Such as $payload.user.name , $payload.manus.0.name |
"$session.FieldName" | Any | Session The number of session fields, supports multi-level access. Such as $session.user.name , $session.manus.0.name value |
"$file.FieldName" | Object File | Upload temporary file structure |
Object File
data structure
Field | Type | Description |
---|---|---|
name | String | file name |
tempfile | String | temporary file address |
size | Integer | file size |
header | [key:String]:Array\<String> | MIME-style header mapping |
Query String | QueryParam | Description |
---|---|---|
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 "," |
{"code": 500,"message": "Data with ID=12 does not exist","context": {"field": "id"}}
Field | Type | Description |
---|---|---|
code | Integer | Error code |
message | String | Error description |
context | Any | exception context information |
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.
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 code | Applicable scenarios | |
---|---|---|
400~499 | The program failed to run due to incorrect input data | |
500~599 | The program fails due to insufficient server resources or abnormal program errors | |
400 | The 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. | |
401 | The program failed to run because you are not logged in. | |
403 | The program failed to run due to insufficient access rights. Specific permission requirement information should be described in the context data. | |
404 | The program failed to run because the query resource does not exist. The resource name and data ID should be described in the context data. | |
413 | The program failed to run because the input data was out of bounds. | |
500 | The 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. | |
503 | The server is temporarily unreachable, causing the program to fail. For example: MySQL server has gone away! | |
504 | Program failed due to connection timeout. For example: MySQL server connect timeout! |
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.
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"}}]}
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