2
votes

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.

2
Yes, because that's how it should be done. If you want to delete username you should make a method with @ DeleteMapping, for adding username with @ PostMapping, for getting it with @ GetMapping So in the end you will have 3+ methods with endpoint /username. Read this article, maybe it will clear some things for you: blog.logrocket.com/… - Szprota21
@Szprota21 Thank you for your response. I have updated my question accordingly. I have patch operation which is responsible for update the resource which i have it like username, description and usergroup. And I need to show multiple example in swagger schema. - Neel

2 Answers

1
votes

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.

0
votes

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