Tags | Webservice, REST |
Type of accelerator | Example project to demonstrate Blueriq functionality and accelerate your learning journey. |
How to get | |
Compatibility | Blueriq 12.13 and higher |
This model shows how error handling can be modeled in Blueriq as a Rest service (BAARS).
The HTTP status code can be used in the model to handle errors. The HTTP status code is a header in the response and can be mapped to an attribute in the model (example below). Blueriq only supports single-valued numeric status codes between 2xx and 5xx. If something else is mapped, the BAARS will throw a 500 message. Mind the capital letter S in Status since the header name is case sensitive.
Input validation is done on the received request. Input validations can be modeled on the domain schema of the request (example below).
For the AQ_RestServiceClient, no validation is performed on the response. |
For REST services based on Domain Schemas, the request is parsed, mapped in the profile and the elements (attributes and relations) are validated. This means that when the validation starts, the profile is complete, so elements from fragments, arguments, headers and request body that depend on each other can also be validated.
For REST services based on XSD schemas, validations are performed on the fly, as the message is being parsed. This means that when the validation of an element starts, the validation rules on that element might depend on other attributes and relations which have not been parsed yet, and whose values at that point are unknown.
By default, validation messages are returned in a single string error message, concatenated with new lines characters. This validation mode is available for both XSD based and Domain Schema based REST services.
POST ../TestApp/0.0-Trunk/Insurance/fragmentTooLong?argumentName=valueTooLong Request Headers ... headerName: valueTooLong ... Request Payload { "insured_person": { "first_name": "John", "last_name": "", "birth_date": "2005-05-10" }, "coverage":[{ "type": "life", "life": { "claim_limit": 100000, "last_health_checkup": "1902-01-01" } }, { "type": "car", "car": { "claim_limit": 5000, "fabrication_date": "1982-01-01" } }] } |
{ "errorMessage": "Unable to handle request, validation messages: First name is required\nPerson must be at least 18 years old to obtain an insurance.\nYou must be over the age of 25 to insure a car older than 10 years.\nYou must be at least 21 years old to be eligible for car insurance.\nName may only be 5 characters long.\nName may only be 5 characters long.\nName may only be 5 characters long." } |
For REST services based on Domain Schemas, input validation can be set to return an extended response in the form of a validation tree of the whole request domain. The validation tree contains four sections: arguments
, body
, fragments
and headers
. In this way, it is easier to identify the instance on which a validation error occurred. By default, this behavior is disabled. For more details on how to enable this functionality, please check the documentation here.
POST ../TestApp/0.0-Trunk/Insurance/fragmentTooLong?argumentName=valueTooLong Request Headers ... headerName: valueTooLong ... Request Payload { "insured_person": { "first_name": "John", "last_name": "", "birth_date": "2005-05-10" }, "coverage":[{ "type": "life", "life": { "claim_limit": 100000, "last_health_checkup": "1902-01-01" } }, { "type": "car", "car": { "claim_limit": 5000, "fabrication_date": "1982-01-01" } }] } |
{ "errorMessage": "There are invalid fields.", "validationTree": { "arguments" : [{ "name": "argumentName", "value": ["valueTooLong"], "validations" : [{ "message": "Name may only be 5 characters long." }] }], "body": { "values": [], "objects": [ { "name": "insured_person", "values": [ { "key": "first_name", "value": "John", "validations": [] }, { "key": "last_name", "value": "", "validations": [ { "message": "Last name is required!" } ] }, { "key": "birth_date", "value": "2005-05-10", "validations": [ { "message": "Person must be at least 18 years old to obtain an insurance." } ] } ], "objects": [], "validations": [] }, { "name": "coverage", "objects": [ { "values": [ { "key": "type", "value": "life", "validations": [] } ], "objects": [ { "name": "life", "values": [ { "key": "claim_limit", "value": "100000.0", "validations": [] }, { "key": "last_health_checkup", "value": "1902-01-01", "validations": [] } ], "objects": [], "validations": [] } ], "validations": [] }, { "values": [ { "key": "type", "value": "car", "validations": [] } ], "objects": [ { "name": "car", "values": [ { "key": "claim_limit", "value": "5000.0", "validations": [] }, { "key": "fabrication_date", "value": "1982-01-01", "validations": [ { "message": "You must be over the age of 25 to insure a car older than 10 years." }, { "message": "You must be at least 21 years old to be eligible for car insurance." } ] } ], "objects": [], "validations": [] } ], "validations": [] } ], "validations": [] } ], "validations": [] }, "fragments": [ "name": "fragmentName", "value": "fragmentTooLong", "validations": [{ "message": "Name may only be 5 characters long." }] ], "headers": [ "name": "headerName", "value": "valueTooLong", "validations": [{ "message": "Name may only be 5 characters long." }] ] } } |
Values returned in the validation messages are from the profile and not directly from the initial request. By being returned from the profile, it means that value formatting applies to the values that are present in the validation message, like in the example below. Please note the number and percentage values from the request and from the response with validation message.
{ "insured_person": { "first_name": "John", "last_name": "Doe", "birth_date": "2018-02-02", "number": "2000", "percentage": "20" } } |
{ "errorMessage": "There are invalid fields.", "validationTree": { "arguments": [], "body": { "values": [], "objects": [ { "name": "insured_person", "values": [ ..., { "key": "birth_date", "value": "2018-02-02", "validations": [ { "message": "Person must be at least 18 years old to obtain an insurance." } ] }, { "key": "number", "value": "2000.0", "validations": [] }, { "key": "percentage", "value": "20.0", "validations": [] } ], "objects": [], "validations": [] } ], "validations": [] }, "fragments": [], "headers": [] } } |
Other considerations on input validation
More complex validations can be handled in the model, using the HTTP status code combined with self created error codes and error messages (example below).
The BAARS will throw an 500 message in case of an unexpected error. In the case of the example this is when one or both input parameters are unknown. This should be handled by another model validation so this can not happen in a production environment.