Java complex validation in Dropwizard?

dropwizard, java, jax-rs, json, validation

Solution

It's not the responsibility of your validation framework to extract the correct polymorphic type and validate it. Infact, by the time validation kicks in, the object has already been created. It can only work with what it has at that point. Note however that:

public Response createCar(@Valid Car car) {
    // ...
}

Will invoke validation on whatever the runtime type of 'car' actually is. So quite obviously what you want to do is assure that the `car` variable is bound at runtime to the correct type. This is the responsibility of your deserialization framework. You will need to determine the correct way to do this with the JSON library being used in your application, but with Jackson you would have used the @JsonTypeInfo annotation to scope your polymorphic types.

@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="kind")
public class Car implements Serializable {
}

Problem

I'd like to accept JSON on an REST endpoint and convert it to the correct type for immediate validation. The endpoint looks like this: ``` @POST public Response createCar(@Valid Car car) { // persist to DB // ... } ``` But there are many subclasses of Car, e.g. Van, SelfDrivingCar, RaceCar, etc. How could I accept the different JSON representations on the endpoint, while keeping the validation code in the Resource as concise as something like `@Valid Car car`? Again: I send in JSON like (here, it's the representation of a subclass of Car, namely SelfDrivingCar): ``` { "id" : "t1", // every Car has an Id "kind" : "selfdriving", // every Car has a type-hint "max_speed" : "200 mph", // some attribute "ai_provider" : "fastcarsai ltd." // this is SelfDrivingCar-specific } ``` and I'd like the validation machinery look into the `kind` attribute, create an instance of the appropriate subclass, here e.g. `SelfDrivingCar` and perform validation. I know I could create different endpoints for all kind of cars, but thats does not seem DRY. And I know that I could use a real `Validator` instead of the annotation and do it by hand, so I'm just asking if there's some elegant shortcut for this problem.

Original source