Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add schema validate admin API #10065

Merged
merged 7 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions apisix/admin/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,41 @@ local function reload_plugins(data, event, source, pid)
end


local function schema_validate()
local uri_segs = core.utils.split_uri(ngx.var.uri)
core.log.info("uri: ", core.json.delay_encode(uri_segs))

local seg_res = uri_segs[6]
local resource = resources[seg_res]
if not resource then
core.response.exit(404, {error_msg = "Unsupported resource type: ".. seg_res})
end

local req_body, err = core.request.get_body(MAX_REQ_BODY)
if err then
core.log.error("failed to read request body: ", err)
core.response.exit(400, {error_msg = "invalid request body: " .. err})
end

if req_body then
local data, err = core.json.decode(req_body)
if err then
core.log.error("invalid request body: ", req_body, " err: ", err)
core.response.exit(400, {error_msg = "invalid request body: " .. err,
req_body = req_body})
end

req_body = data
end

local ok, err = core.schema.check(resource.schema, req_body)
if ok then
core.response.exit(200)
end
core.response.exit(400, {error_msg = err})
end


local uri_route = {
{
paths = [[/apisix/admin]],
Expand All @@ -392,6 +427,11 @@ local uri_route = {
methods = {"GET"},
handler = get_plugins_list,
},
{
paths = [[/apisix/admin/schema/validate/*]],
methods = {"POST"},
handler = schema_validate,
},
{
paths = reload_event,
methods = {"PUT"},
Expand Down
49 changes: 49 additions & 0 deletions docs/en/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1514,3 +1514,52 @@ Proto resource request address: /apisix/admin/protos/{id}
| content | True | String | content of `.proto` or `.pb` files | See [here](./plugins/grpc-transcode.md#enabling-the-plugin) |
| create_time | False | Epoch timestamp (in seconds) of the created time. If missing, this field will be populated automatically. | 1602883670 |
| update_time | False | Epoch timestamp (in seconds) of the updated time. If missing, this field will be populated automatically. | 1602883670 |

## Schema validation

Check the validity of a configuration against its entity schema. This allows you to test your input before submitting a request to the entity endpoints of the Admin API.

Note that this only performs the schema validation checks, checking that the input configuration is well-formed. Requests to the entity endpoint using the given configuration may still fail due to other reasons, such as invalid foreign key relationships or uniqueness check failures against the contents of the data store.

### Schema validation

Schema validation request address: /apisix/admin/schema/validate/{resource}

### Request Methods

| Method | Request URI | Request Body | Description |
| ------ | -------------------------------- | ------------ | ----------------------------------------------- |
| POST | /apisix/admin/schema/validate/{resource} | {..resource conf..} | Validate the resource configuration against corresponding schema. |

### Request Body Parameters

* 200: validate ok.
* 400: validate failed, with error as response body in JSON format.

Example:

```bash
curl http://127.0.0.1:9180/apisix/admin/schema/validate/routes \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X POST -i -d '{
"uri": 1980,
"upstream": {
"scheme": "https",
"type": "roundrobin",
"nodes": {
"nghttp2.org": 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"nghttp2.org": 1
"httpbin.org": 1

Copy link
Contributor Author

@kingluo kingluo Aug 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

httpbin has been less stable in recent months, and now the community is using nghttp2 more.
Also, regarding schema checking, what matters here is not the actual value, but the type.

Copy link
Member

@tao12345666333 tao12345666333 Aug 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes.

FYI We can use httpbun.org also

This does not affect this PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about https://mock.api7.ai/?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moonming SGTM.

}
}
}'
HTTP/1.1 400 Bad Request
Date: Mon, 21 Aug 2023 07:37:13 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.4.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: *
Access-Control-Max-Age: 3600

{"error_msg":"property \"uri\" validation failed: wrong type: expected string, got number"}
```
Loading
Loading