Reputation: 2183
I have an API Gateway POST endpoint that takes in a JSON request body. I have turned on the body request validator and added the request body model. However the error response I'm getting is only some generic message: "message": "Invalid request body"
as defined in the Gateway responses. I'm wondering if it is possible to include the specific validation error in the response? In the logs it says specifically
Request body does not match model schema for content type application/json:
[object has missing required properties (["property1","property2",...])]
Is it possible to have something similar to this in the actual response? Thank you.
Upvotes: 8
Views: 15779
Reputation: 49
TLDR; If you are using an Open API spec, Add this to the root of your Open API spec:
x-amazon-apigateway-gateway-responses:
BAD_REQUEST_PARAMETERS:
statusCode: 400
responseTemplates: application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString \n }"
BAD_REQUEST_BODY:
statusCode: 400
responseTemplates: application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString \n }"
Explained:
If you are using an Open API spec (Yaml file), you can add some default error handlers of a predefined set of 'Gateway responses' to the root of your open API spec and configure them to return specific information by using the 'context' (a set of variables).
There is a limited set of Gateway responses, here is a list: https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html
And here is the variables available via the context: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variables-template-example
Here is an example of what I return in an error:
{
"message": "Bad Request",
"cause": "Missing value ...",
"code": "LTAPI_400",
"X-Transaction-ID": "io7b3c78vtv87baxd324"
}
So my 'x-amazon-apigateway-gateway-responses' are:
x-amazon-apigateway-gateway-responses:
ACCESS_DENIED:
statusCode: 401
responseTemplates:
application/json: "{\n \"message\": \"$context.authorizer.context.error_type\", \n \"cause\": \"$context.authorizer.context.error_message\", \n \"code\": LTAPI_401, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
AUTHORIZER_FAILURE:
statusCode: 503
responseTemplates:
application/json: "{\n \"message\": \"Service Unavailable\", \n \"cause\": \"The request couldn't be completed successfully because of an error in a downstream system.\", \n \"code\": LTAPI_503, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
AUTHORIZER_CONFIGURATION_ERROR:
statusCode: 503
responseTemplates:
application/json: "{\n \"message\": \"Service Unavailable\", \n \"cause\": \"The request couldn't be completed successfully because of an error in a downstream system.\", \n \"code\": LTAPI_503, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
BAD_REQUEST_PARAMETERS:
statusCode: 400
responseTemplates:
application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString, \n \"code\": LTAPI_400, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
BAD_REQUEST_BODY:
statusCode: 400
responseTemplates:
application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString, \n \"code\": LTAPI_400, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
DEFAULT_5XX:
statusCode: 500
responseTemplates:
application/json: "{\n \"message\": \"Internal Server Error\", \n \"cause\": \"An unexpected error has occurred.\", \n \"code\": LTAPI_500, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
Upvotes: 1
Reputation: 452
In Gateway response for error type BAD_REQUEST_BODY error status 400
set Application/json to {"message":$context.error.validationErrorString}
Ref https://stackoverflow.com/a/48014686
Upvotes: 8
Reputation: 392
AWS API Gateway will include more details only if the request payload format is valid, but parameters format is invalid:
{
"message": "Missing required request parameters: [p1]"
}
If the request payload is invalid, you will always receive the same message:
{
"message": "Invalid request body"
}
See the bottom of following page:
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-validation-test.html
The only way you can get more details is through logs.
By the way, why do you want to send more details through your API, is it for development and debugging only? If yes, using logs is the way to go. You may have some log processing and storage solution to make your debugging easier (e.g. Splunk, Data Dog, Sumo Logic, etc.)
Otherwise, in general, returning too much of technical details in your API error messages is something to avoid.
Upvotes: 2