oas-validator
The oas-validator plugin allows validation of HTTP requests and responses against a defined API specification that complies with Open API v3 specification.
Examples
The Swagger Petstore Open API spec will be used in the examples below.
export OPEN_API_SPEC=$(curl -s "https://petstore3.swagger.io/api/v3/openapi.json" | sed 's/"/\\"/g')
Validate Request Body
This example demonstrates validation of request body against a given specification.
Create the following route with the OAS validator plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "body_validation",
"uri": "/*",
"plugins": {
"oas-validator": {
"spec": "'"${OPEN_API_SPEC}"'"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"petstore3.swagger.io:443": 1
},
"scheme": "https",
"pass_host": "node"
}
}'
Failed Validation
Send a request to the above route with a request body that does not satisfy the defined Open API Spec:
curl -i "http://127.0.0.1:9080/api/v3/pet" -X POST \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"invalid-body": "this is an invalid body"}'
You should see an HTTP/1.1 400 Bad Request response with the response body similar to the following:
{"message":"failed to validate request."}
Successful Validation
Send a request to the route with a valid request body:
curl -i "http://127.0.0.1:9080/api/v3/pet" -X POST \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "doggie",
"category": { "id": 1, "name": "Dogs" },
"photoUrls": ["string"],
"tags": [{ "id": 1, "name": "tag1" }],
"status": "available"
}'
You should see an HTTP/1.1 200 OK response with the response body similar to the following:
{
"id": 1,
"category": { "id": 1, "name": "Dogs" },
"name": "doggie",
"photoUrls": ["string"],
"tags": [{ "id": 1, "name": "tag1" }],
"status": "available"
}
Get Verbose Error Response
This example demonstrates getting verbose error response when the validation fails.
Create a route with the OAS Validator plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "body_validation",
"uri": "/*",
"plugins": {
"oas-validator": {
"spec": "'"${OPEN_API_SPEC}"'",
"verbose_errors": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"petstore3.swagger.io:443": 1
},
"scheme": "https",
"pass_host": "node"
}
}'
Send a request to the route created above with an invalid request body:
curl -i "http://127.0.0.1:9080/api/v3/pet" -X POST \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"invalid-body": "this is an invalid body"}'
You should see an HTTP/1.1 400 Bad Request response with the response body similar to the following:
doesn't match schema #/components/schemas/Pet: Error at "/name": property "name" is missing
Schema:
{
"properties": {
"category": {
"$ref": "#/components/schemas/Category"
},
"id": {
"example": 10,
"format": "int64",
"type": "integer"
},
...
}
Value:
{
"invalid-body": "this is an invalid body"
}
| Error at "/photoUrls": property "photoUrls" is missing
Schema:
{
"properties": {
"category": {
"$ref": "#/components/schemas/Category"
},
...
}
Value:
{
"invalid-body": "this is an invalid body"
}
Monitor Violations Without Blocking Traffic
Use reject_if_not_match to control whether non-compliant requests are blocked or allowed through. This example applies only to API7 Enterprise from version 3.9.6 and is not applicable in APISIX.
Reject Non-Compliant Requests
When reject_if_not_match is set to true (default), requests that fail OAS validation are blocked with a HTTP/1.1 400 Bad Request response.
Create a route with the OAS Validator plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "body_validation",
"uri": "/*",
"plugins": {
"oas-validator": {
"spec": "'"${OPEN_API_SPEC}"'",
"reject_if_not_match": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"petstore3.swagger.io:443": 1
},
"scheme": "https",
"pass_host": "node"
}
}'
Send a request with an invalid body:
curl -i "http://127.0.0.1:9080/api/v3/pet" -X POST \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"invalid-body": "this is an invalid body"}'
You should see an HTTP/1.1 400 Bad Request response with the response body similar to the following:
{"message":"failed to validate request."}
Allow Non-Compliant Requests to Pass
When reject_if_not_match is set to false, non-compliant requests are forwarded to the upstream instead of being blocked, and validation errors are recorded in the error logs.
Update the route to set reject_if_not_match to false:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "body_validation",
"uri": "/*",
"plugins": {
"oas-validator": {
"spec": "'"${OPEN_API_SPEC}"'",
"reject_if_not_match": false
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"petstore3.swagger.io:443": 1
},
"scheme": "https",
"pass_host": "node"
}
}'
Send a request with an invalid body:
curl -i "http://127.0.0.1:9080/api/v3/pet" -X POST \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"invalid-body": "this is an invalid body"}'
You should see an HTTP/1.1 500 Internal Server Error response since petstore3.swagger.io does not correctly handle an invalid body. However, you can see that the request got passed successfully to the upstream.
You should also see an error log capturing the method, URI, and validation error similar to this:
[error] error occurred while validating request [POST /api/v3/pet], err: ...
This lets you audit non-compliant traffic in your logs without breaking existing clients.