Gobliins
Gobliins

Reputation: 4026

Swagger API consuming json with json validation

I am using Swagger to generate a Restful API:

@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
@io.swagger.annotations.ApiOperation(value = "Create a task", notes = "", response = Tasks.class)
@io.swagger.annotations.ApiResponses(value = { 
    @io.swagger.annotations.ApiResponse(code = 200, message = "created task", response = Tasks.class),
    @io.swagger.annotations.ApiResponse(code = 404, message = "task not found", response = Tasks.class),
    @io.swagger.annotations.ApiResponse(code = 200, message = "unexpected error", response = Tasks.class) })
public Response createTask(@ApiParam(value = "The task to create" ,required=true ) NewTask newTask)
throws NotFoundException {
    return delegate.createTask(newTask);
}

This API accepts json strings and generates java objects from it. This is working quiet well with one exception: The API accepts any correct formed json string but ignores the content of the json which means i get an object created with default values.

So my question is: How can i validate the incoming jsonstring ( against a json schema) before the actual java object is generated?

Upvotes: 1

Views: 2835

Answers (2)

Sven Döring
Sven Döring

Reputation: 4368

There is the swagger-request-validator having several adapters for various frameworks, e.g.: Spring Web MVC

It is capable of validating requests and / or responses against Swagger / OpenAPI 2 or OpenAPI 3 schemes.

See here: Validating JSON messages against Swagger definition in Java for a more detailed answer.

Upvotes: 0

cassiomolin
cassiomolin

Reputation: 130877

Since you don't want to receive a JSON String in your methods and Bean Validation is not an option for your validation, you could try a MessageBodyWriter<T>.

JAX-RS uses MessageBodyWriter<T>s to parse incoming requests. Since you want something very specific, consider writing your own MessageBodyWriter<T>.

See the following example:

@Provider
@Produces("application/json")
public class CustomMessageBodyWriter implements MessageBodyWriter<Object> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return true;
    }

    @Override
    public long getSize(MyBean myBean, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {

        // Deprecated by JAX-RS 2.0
        return 0;
    }

    @Override
    public void writeTo(Object object, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream) throws IOException {

        // Read the entityStream
        // Perform the validation against your schema
        // Write to the object
    }
}

The @Provider annotation makes the class to be automatically discovered by the JAX-RS runtime during a provider scanning phase.

Upvotes: 1

Related Questions