How can I manually document Swagger datamodel for a JAX-RS parameter?

sno*_*e92 11 java swagger

Context

Let's say that I have a simple data class in Java:

public class Person {
    private final String name;
    private final int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    int String getAge() {
        return age;
    }
}
Run Code Online (Sandbox Code Playgroud)

Note: in practice, I use Immutables to generate this, but am showing a POJO here for the sake of simplicity.

To document the model of the GET response, even if the return type is Response, I can refer to the class in @ApiOperation:

@GET
@ApiOperation(response = Person.class)
public Response getPerson() {
    return Response.ok(new Person("Julien", 28)).build();
}
Run Code Online (Sandbox Code Playgroud)

Based on that, Swagger will document this correctly:

Model:

Person {
  name (string),
  age (number)
}
Run Code Online (Sandbox Code Playgroud)

Example value:

{
  "name": "string",
  "age": 0
}
Run Code Online (Sandbox Code Playgroud)

To document the model of the POST body, I use the class directly in the code, Swagger finds it and documents it as desired:

Person {
  name (string),
  age (number)
}
Run Code Online (Sandbox Code Playgroud)

Problem

I want to support partial updates as well. I cannot use the POJO itself, because all fields are mandatory in the POJO, I rely on that to get safe checks and clear error messages when invalid JSON is sent to e.g. the POST method.

In my actual use-case, my datamodel contains maps. I want users to be able to specify a certain key in the update and set the value to null, to delete elements from an existing maps.

I chose to support PATCH requests where the body is typed as a plain JsonNode. That allows any JSON to be received by my server and I can apply the updates as I wish.

{
  "name": "string",
  "age": 0
}
Run Code Online (Sandbox Code Playgroud)

I'm happy with the result, except that Swagger now documents the partial update's model with the properties of the JsonNode Java object:

Model:

JsonNode {
  array (boolean, optional),
  null (boolean, optional),
  number (boolean, optional),
  float (boolean, optional),
  pojo (boolean, optional),
  valueNode (boolean, optional),
  containerNode (boolean, optional),
  object (boolean, optional),
  missingNode (boolean, optional),
  nodeType (string, optional) = ['ARRAY', 'BINARY', 'BOOLEAN', 'MISSING', 'NULL', 'NUMBER', 'OBJECT', 'POJO', 'STRING'],
  integralNumber (boolean, optional),
  floatingPointNumber (boolean, optional),
  short (boolean, optional),
  int (boolean, optional),
  long (boolean, optional),
  double (boolean, optional),
  bigDecimal (boolean, optional),
  bigInteger (boolean, optional),
  textual (boolean, optional),
  boolean (boolean, optional),
  binary (boolean, optional)
}
Run Code Online (Sandbox Code Playgroud)

Example value:

{
  "array": true,
  "null": true,
  "number": true,
  "float": true,
  "pojo": true,
  "valueNode": true,
  "containerNode": true,
  "object": true,
  "missingNode": true,
  "nodeType": "ARRAY",
  "integralNumber": true,
  "floatingPointNumber": true,
  "short": true,
  "int": true,
  "long": true,
  "double": true,
  "bigDecimal": true,
  "bigInteger": true,
  "textual": true,
  "boolean": true,
  "binary": true
}
Run Code Online (Sandbox Code Playgroud)

I would like to specify in my code that the model is like Person, so that the example given in the Swagger UI is more relevant. I did try @ApiImplicitParams:

@POST
@ApiOperation(response = Person.class)
public Response addPerson(Person newPerson) {
    return Response.ok(store.insert(newPerson)).build();
}
Run Code Online (Sandbox Code Playgroud)

That did not make any difference. Swagger still documents JsonNode itself. The documentation for @ApiImplicitParams mentions:

While ApiParam is bound to a JAX-RS parameter, method or field, this allows you to manually define a parameter in a fine-tuned manner. This is the only way to define parameters when using Servlets or other non-JAX-RS environments.

Since I am using JAX-RS, this might mean that I cannot use @ApiImplicitParams, but @ApiParam does not provide anything to override the class.

How can I specify manually the datamodel of a JAX-RS parameter that is detected by Swagger automatically?

Shu*_*lag 2

添加此答案是为了使其具有一定的通用性,以便更好地理解@ApiImplicitParams.

您必须按照@ApiImplicitParams您希望保存在文档中的方式来包装参数。 @ApiImplicitParam有许多不那么明显的好处,比如传递额外的标头参数而不将其添加为方法参数,或者在您的情况下包装参数以使它们有意义。

对于您的问题,您必须使用@ApiImplicitParamwithparamType = "body"来更改正文,类似地,paramType = "head"如果您想更改标题。

@ApiImplicitParam您还可以使用 property控制必填字段required = true/false

如前所述,您可以传递参数而无需将其放在方法参数中,您可以使用属性控制其值value = "required value"

@ApiImplicitParam您还可以使用逗号分隔值来控制允许的值。例如。allowableValues = "no-cache, no-store"