Neel
Neel

Reputation: 253

How to show multiple example in swagger documentation?

In my REST API PATCH operation, I am using v3 swagger-annotation:2.0.6

I was trying to add more examples as swagger schema for my patch operation PATCH /users/id.

Request Body:

{
  "operationList": [
    {
      "op": "replace",
      "path": "/username",
      "value": "john1991"
    }
  ]
}

Currently I have following class for request model.

public class UserPatchOp extends PatchOperation {
    @Override
    @Schema(description = "some description", example = "replace", required = true)
    public PatchOperator getOp() {
        return super.getOp();
    }

    @Override
    @Schema(description = "some description", example = "/username", required = true)
    public String getPath() {
        return super.getPath();
    }

    @Override
    @Schema(description = "some description", , example = "john1991", required = true)
    public Object getValue() {
        return super.getValue();
    }
}

In PatchOperation.java

public class PatchOperation {

    /**
     * {@link PatchOperator} operation to be performed
     */
    @Schema(description = "Operation to be performed", required = true)
    @JsonProperty
    @NotNull
    private PatchOperator op;

    @Schema(description = "Path to target where operation will be performed", required = true)
    @JsonProperty
    @Pattern(regexp = "/([/A-Za-z0-9~])*-*", message = "Invalid path. Please follow regex pattern")
    private String path;

    @Schema(description = "Value used by operation")
    @JsonProperty
    private Object value;

    public PatchOperation() {
    }
}

In the swagger document, in UserPatchOp.java I have shown to the end-user that how to replace username. On swagger, the request bogy comes with this example.

enter image description here

other than username through this patch operation, end-user can update description then path would be /description.

End-user can also update the usergroup from which it belongs to '/usergroups' So in general, same way I want to add more example to swagger schema. But I am not able to do it. Because at one time I can show one example only.

I want to show following multiple operations to the client on swagger page.

{
  "operationList": [
    {
      "op": "replace",
      "path": "/username",
      "value": "john1991"
    },
    {
      "op": "remove",
      "path": "/description"
    },
    {
      "op": "add",
      "path": "/memberships"
      "value":["1224","8907"]
    }
  ]
}

And entry point method is

@PATCH

@Path("users/{id}")
@Consumes({MediaType.APPLICATION_JSON, APPLICATION_JSON_PATCH_JSON})
@ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = MessageConstants.OK, content = @Content(schema = @Schema(implementation = UserInfo.class))),
        @ApiResponse(responseCode = "500", description = MessageConstants.SERVER_ERROR, content = @Content(schema = @Schema(implementation = RestError.class))),
        @ApiResponse(responseCode = "400", description = MessageConstants.BAD_REQUEST, content = @Content(schema = @Schema(implementation = RestError.class))),
        @ApiResponse(responseCode = "401", description = MessageConstants.UNAUTHORIZED, content = @Content(schema = @Schema(implementation = RestError.class))),
        @ApiResponse(responseCode = "404", description = MessageConstants.NOT_FOUND, content = @Content(schema = @Schema(implementation = RestError.class)))})
public Response updatePartialUser(
        @Parameter(description = "User Id", required = true) @PathParam("id") String id,
        @Parameter(description = "User Update Info", required = true) @Valid PatchOperations<UserPatchOperation> operationList) {

Is there any way, I can add multiple examples for getOP, getPath and getValue method? Thank you.

Upvotes: 4

Views: 8859

Answers (2)

Neel
Neel

Reputation: 253

I have added example at entry point with help of schema

@Parameter(description = "Update User", required = true, schema = @Schema (example = "{\n  "
                    + "\"operationList\": [\n    "
                    + "{\n      \"op\": \"replace\",\n      \"path\": \"/username\",\n      \"value\": \"john1991\"\n    },\n    "
                    + "{\n      \"op\": \"replace\",\n      \"path\": \"/description\",\n      \"value\": \"NewDescription\"\n    },\n    "
                    + "{\n      \"op\": \"add\",\n      \"path\": \"/memberships\",\n      "
                    + "\"value\":[\"1234\",\"6789\"]\n    "
                    + "{\n      \"op\": \"remove\",\n      \"path\": \"/privileges\",\n      \"value\":[\"148\",\"155\"]\n    "
                    + "}\n  ]\n}")) @Valid PatchOperations<UserPatchOperation> operationList) throws RestException

Upvotes: 0

Morph21
Morph21

Reputation: 1207

It is possible to create multiple examples of responses which one method can return but it is possible to do only one example for one response code.

@Operation(description = "Retrieves status of application",
               responses = {
                       @ApiResponse(responseCode = "200",
                                    description = "Everything works fine.",
                                    content = @Content(mediaType = "application/json",
                                                       examples = @ExampleObject(value = "{\n" +
                                                                                         "  \"success\" : true,\n" +
                                                                                         "  \"message\" : \"OK\"\n" +
                                                                                         "}"))),
                       @ApiResponse(responseCode = "500",
                                    description = "Application not working properly",
                                    content = @Content(mediaType = "application/json",
                                                       examples = @ExampleObject(value = "{\n" +
                                                                                         "  \"success\" : false,\n" +
                                                                                         "  \"message\" : \"Application not working properly\"\n" +
                                                                                         "}")))
               })
    @GetMapping("haproxy")
    ResponseEntity<BaseResponse> getHaProxy();

I'm not sure if it's what you want but I don't see other way around.

Keep in mind that swagger documentation should be done in a way that someone will be able connect to your api and do some operations. You don't need to provide too much responses there. That's for OPTIONS rest method is. OPTIONS method is basically a GET which don't need any parameters and in response will return complete informations about what certain method can do and what the request/response will be. Here you have better explanation of that: RESTful API methods; HEAD & OPTIONS

Btw. you should update your dependencies, swagger-annotations is on 2.1.4 now, 2.0.6 is from 2 years ago

EDIT 2020-09-30 About request's body:

It is possible to add multiple requests examples like that:

@Operation(description = "Creates a User",
           requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Request examples",
                                                                               content = @Content(examples = {
                                                                                       @ExampleObject(name = "doing weird stuff", value = "http://localhost:7080"),
                                                                                       @ExampleObject(name = "doing weirdest stuff", value = "{\n\"test\":\"12\"\n}"),
                                                                               })),
           responses = {
                   @ApiResponse(responseCode = "200",
                                description = "Everything works fine.",
                                content = @Content(mediaType = "application/json",
                                                   schema = @Schema(implementation = UserResponse.class))),
                   @ApiResponse(responseCode = "404",
                                description = "Not found",
                                content = @Content(mediaType = "application/json",
                                                   examples = @ExampleObject(value = "{\"success\":false,\"message\":\"That shop or API version is not accessible yet\",\"httpStatus\":\"NOT_FOUND\"}"))),
                   @ApiResponse(responseCode = "500",
                                description = "Something went wrong",
                                content = @Content(mediaType = "application/json",
                                                   schema = @Schema(implementation = SomeBasicResponse.class)))
           })
@Parameters({
                    @Parameter(in = ParameterIn.HEADER, name = "url",
                               content = @Content(schema = @Schema(type = "string", defaultValue = "localhost:7080")))
            })

@PostMapping
ResponseEntity<UserResponse> createUser(@RequestHeader(name = "login", required = false) String login,
                                              @RequestHeader(name = "password") String password,
                                              @RequestBody UserRequest request);

RequestBody example No. 1

RequestBody example No. 2

I hope that's what you are looking for.

Upvotes: 3

Related Questions