1
votes

I am trying to use Swagger to document a Spring-MVC based REST-API and am having problems getting Swagger to reflect the use of custom serializers and deserializers.

Because the JSON must conform to an established format (which is not particularly well designed) and I wanted to have a properly designed API model in the Java classes, I have used a few custom implementations of JsonSerializer to generate the JSON output. When I enable Swagger with annotations in the Spring-MVC controllers, the generated documentation ignores the custom serializers and describes the model as if it had been serialized with the default Jackson settings. So far so good, I didn't really expect Swagger to automatically understand the implementation of the serializers.

What I however would expect (and I can't find anything about this in the Swagger documentation) is a way to use Swagger annotations on the relevant attributes in the model classes to manually describe the model. Am I missing something or is it really not possible to Swagger as a documentation tool in connection with custom serializers (or deserializers for that matter)?

Edit: The Swagger documentation is not particularly good, but I have already tried to work with @ApiModelProperty on the deviating properties. As far as I can see, it has absolutely no effect on the generated output (tested with Swagger-SpringMVC 0.8.5 and 0.9.5).

1

1 Answers

1
votes

You can use model substitutes for e.g. Lets say you have a service

@RequestMapping(value = { "/some-resource" }, method = POST, 
    consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Void> 
    businessTypeEcho(@RequestBody CustomSerializableResource business) {
    return new CustomSerializableResource();
}

you can setup a type substitution rule that tells springmvc how to represent the custom serializable type in the swagger ui.

@Bean //Don't forget the @Bean annotation
public SwaggerSpringMvcPlugin customImplementation(){
   return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
        .apiInfo(apiInfo())
        .directModelSubstitute(CustomSerializableResource.class, SubstitutedSerializableResource.class)
        .includePatterns(".*pet.*");
}

class SubstitutedSerializableResource {
    //getters and setters that describe what 
    //CustomSerializableResource should look like in the UI
}

Unfortunately, this is going to create a parallel universe of types that aren't used at runtime.

Update: If I understand your comment correctly, you're using it to format system-wide types i.e. booleans to Y/N or dates to mm/dd/yyyy perhaps. IMO, what you're probably looking for is to use model substitutes (see example above).

  • Substitute Date with String (this is the prescriptive guidance) In the case of dates your only option to communicate the format expected unfortunately is only via a textual description of the particular field or property.
  • Substitute Boolean with a enum you can create i.e. YesNoEnum that represents how you expect the objects to be serialized. This will provide the documentation with a set of allowed values.

At the end of the day, its a trade-off between creating these meta classes just for documentation vs. standardizing the API models to use serialization primitives as much as possible.