I have Java endpoint which receives json-deserializable object. Unfortunately, Swagger is unable to auto-generate good example for it. Is it possible to provide completely custom JSON for an example?
Example is below, regard class Body. It has two fields.
One field is a Set. I want to provide some example list of values for it. I can't use example parameter for this.
Another field is a Parent. It can contain one of two of subclessed, Child1 and Child2. Springfox generates me
{
"parent": {
"@child#": "string"
},
"tags": "[\"tag1\", \"tag2\"]"
}
and I can't send this value (it's incorrect serialization). While I want to have
{
"parent": {
"@child#": "1",
"field1": "value of field 1"
},
"tags": ["tag1", "tag2"]
}
The code:
package com.example.demo;
import java.io.IOException;
import java.util.Set;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@RestController
@SpringBootApplication
@Configuration
@EnableOpenApi
public class DemoApplication {
@PostMapping(value = "/create", consumes = MediaType.APPLICATION_JSON_VALUE)
public Body create(@RequestBody Body body) {
return body;
}
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30)
.select()
.apis(RequestHandlerSelectors.basePackage(DemoApplication.class.getPackageName()))
.paths(PathSelectors.any())
.build()
//.apiInfo(apiInfo())
//.securitySchemes(Collections.singletonList(apiKey()))
//.protocols(getProtocols(systemSettings))
;
}
public static class Body {
@ApiModelProperty(example = "[\"tag1\", \"tag2\"]")
public Set<String> tags;
public Parent parent;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "@child#", include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true)
@JsonTypeIdResolver(MyTypeIdResolver.class)
@ApiModel(discriminator = "@child#")
public static class Parent {
final String childTypeNumber;
@JsonProperty("@child#")
public String childTypeNumber() {
return childTypeNumber;
}
public Parent(String childTypeNumber) {
this.childTypeNumber = childTypeNumber;
}
}
public static class MyTypeIdResolver extends TypeIdResolverBase {
private JavaType superType;
@Override
public void init(JavaType baseType) {
superType = baseType;
}
@Override
public String idFromValue(Object value) {
return null;
}
@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
return null;
}
@Override
public JsonTypeInfo.Id getMechanism() {
return null;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
char c = id.charAt(0);
Class<?> subType = null;
switch (c) {
case '1':
subType = Child1.class;
break;
case '2':
subType = Child2.class;
break;
default:
throw new RuntimeException("Invalid Child type");
}
return context.constructSpecializedType(superType, subType);
}
}
public static class Child1 extends Parent {
public String field1;
public Child1() {
super("1");
}
}
public static class Child2 extends Parent {
public String field2;
public Child2() {
super("2");
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}