<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-openapi</artifactId>
<version>4.5.11</version>
</dependency>
Vert.x OpenAPI
Vert.x OpenAPI extends Vert.x to support OpenAPI 3 in version 3.0 and 3.1.
Vert.x OpenAPI can:
-
parse and validate your OpenAPI contract.
-
parse and validate incoming requests according to your OpenAPI contract.
-
parse and validate outgoing responses according to your OpenAPI contract.
Using Vert.x OpenAPI
To use Vert.x OpenAPI, add the following dependency to the dependencies section of your build descriptor:
-
Maven (in your
pom.xml
):
-
Gradle (in your
build.gradle
file):
dependencies {
compile 'io.vertx:vertx-openapi:4.5.11'
}
OpenAPIContract
When using Vert.x OpenAPI you always start with creating an instance of OpenAPIContract
from your contract.
String pathToContract = ".../.../myContract.json"; // json or yaml
Future<OpenAPIContract> contract = OpenAPIContract.from(vertx, pathToContract);
Due to security reasons this library is not downloading external references from your contract. In case your contract requires external resources, they must be downloaded upfront and also provided to the OpenAPIContract . |
The example below shows a snippet from an example OpenAPI contract that includes a reference to an external resource and how to create an instance of OpenAPIContract
.
paths:
/pets:
get:
operationId: listPets
parameters:
- name: query
schema:
$ref: 'https://example.com/pet-components#/components/schemas/Query'
String pathToContract = ".../.../myContract.json"; // json or yaml
String pathToComponents = ".../.../myComponents.json"; // json or yaml
Map<String, String> additionalContractFiles = new HashMap<>();
additionalContractFiles.put("https://example.com/pet-components",
pathToComponents);
Future<OpenAPIContract> contract =
OpenAPIContract.from(vertx, pathToContract, additionalContractFiles);
During the instantiation of OpenAPIContract the contract gets validated. In case your contract does not match the OpenAPI specification or uses features which are not yet supported an error is thrown. |
Path, Operation, Parameter
The OpenAPIContract
interface offers methods to navigate to the Path
, Operation
and Parameter
objects of the OpenAPI contract.
OpenAPIContract contract = getContract();
for (Path path : contract.getPaths()) {
for (Parameter pathParameter : path.getParameters()) {
// example methods of a OpenAPI parameter object
pathParameter.isRequired();
pathParameter.getSchema();
}
for (Operation operation : path.getOperations()) {
// example methods of a OpenAPI operation object
operation.getOperationId();
operation.getRequestBody();
operation.getParameters();
}
}
Validation of Requests
The RequestValidator
offers multiple validate methods to validate incoming requests.
OpenAPIContract contract = getContract();
RequestValidator validator = RequestValidator.create(vertx, contract);
vertx.createHttpServer().requestHandler(httpServerRequest -> {
// Operation id must be determined for every request which is inefficient
validator.validate(httpServerRequest).onSuccess(validatedRequest -> {
validatedRequest.getBody(); // returns the body
validatedRequest.getHeaders(); // returns the header
// ..
// ..
});
// Operation id will be passed to save effort for determining
validator.validate(httpServerRequest, "yourOperationId")
.onSuccess(validatedRequest -> {
// do something
});
}).listen(0);
The RequestValidator
also offers a signature of the validate method that consumes a ValidatableRequest
.
OpenAPIContract contract = getContract();
RequestValidator validator = RequestValidator.create(vertx, contract);
ValidatableRequest request = getValidatableRequest();
validator.validate(request, "yourOperationId").onSuccess(validatedRequest -> {
validatedRequest.getBody(); // returns the body
validatedRequest.getHeaders(); // returns the header
// ..
// ..
});
The parameters in a ValidatableRequest must be stored in a specific format depending on the style, location and if they are exploded or not, otherwise the RequestValidator can’t validate the request. The required format MUST exactly look like as described in the JavaDoc of RequestValidator . |
Validation of Responses
The ResponseValidator
offers a validate method to validate responses. ValidatableResponse
offers multiple create methods to build validatable responses easily.
In case that the validation of a response has passed, the returned ValidatedResponse
can directly be sent back to the client.
OpenAPIContract contract = getContract();
ResponseValidator validator = ResponseValidator.create(vertx, contract);
JsonObject cat = new JsonObject().put("name", "foo");
ValidatableResponse response =
ValidatableResponse.create(200, cat.toBuffer(), APPLICATION_JSON.toString());
vertx.createHttpServer().requestHandler(httpServerRequest -> {
validator.validate(response, "yourOperationId")
.onSuccess(validatedResponse -> {
validatedResponse.getBody(); // returns the body
validatedResponse.getHeaders(); // returns the header
// ..
// ..
// send back the validated response
validatedResponse.send(httpServerRequest.response());
});
});
The parameters in a ValidatableResponse must be stored in a specific format depending on the style, location and if they are exploded or not, otherwise the ResponseValidator can’t validate the response. The required format MUST exactly look like as described in the JavaDoc of ResponseValidator . |
Handle Validation Exceptions
A ValidatorException
is thrown, if the validation of a request or response fails. The validation can fail for formal reasons, such as the wrong format for a parameter or the absence of a required parameter. However, validation can of course also fail because the content does not match the defined schema. In this case a SchemaValidationException
is thrown. It is a subclass of ValidatorException and provides access to the related OutputUnit
to allow further analysis of the error.