Skip to content

JsonView with a pageable response doesn't respect variables #3224

@jdrtechsolutions

Description

@jdrtechsolutions

Describe the bug

When using @JSONVIEW on an controller that returns an pagable object, it will not respect the variables of the content object.

To Reproduce
Steps to reproduce the behavior:

  • What version of spring-boot you are using?
    4.0.3

  • What modules and versions of springdoc-openapi are you using?
    3.0.1 - springdoc-openapi-starter-webmvc-ui & springdoc-openapi-starter-common

  • What is the actual and the expected result using OpenAPI Description (yml or json)?
    It shows me all the variables of the underlying object ignoring the JsonView.
    I expect that it will only show the variables of the underlying object with the JsonView that belongs to the content object.

  • Provide with a sample code (HelloController) or Test that reproduces the problem

HelloController.java

@RestController
public class HelloController {

    @JsonView(View.Hello.class)
    @GetMapping(produces = APPLICATION_JSON_VALUE)
    public ResponseEntity<Page<HelloWorld>> getHelloWorldPaged(@ParameterObject Pageable pageable) {
        return ResponseEntity.ok(new PageImpl<>(List.of(new HelloWorld("hello", "world")), pageable, 1));
    }

}

HelloWorld.java

public record HelloWorld(@JsonView(View.Hello.class) String hello,
                         @JsonView(View.World.class) String world) { }

api-docs

{
  "openapi": "3.1.0",
  "info": {
    "title": "OpenAPI definition",
    "version": "v0"
  },
  "servers": [
    {
      "url": "http://localhost:8092",
      "description": "Generated server url"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "hello-controller"
        ],
        "operationId": "getHelloWorldPaged",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index (0..N)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "The size of the page to be returned",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PagedModelHelloWorld"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HelloWorld": {
        "type": "object",
        "properties": {
          "hello": {
            "type": "string"
          },
          "world": {
            "type": "string"
          }
        }
      },
      "PageMetadata": {
        "type": "object",
        "properties": {
          "size": {
            "type": "integer",
            "format": "int64"
          },
          "number": {
            "type": "integer",
            "format": "int64"
          },
          "totalElements": {
            "type": "integer",
            "format": "int64"
          },
          "totalPages": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "PagedModelHelloWorld": {
        "type": "object",
        "properties": {
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HelloWorld"
            }
          },
          "page": {
            "$ref": "#/components/schemas/PageMetadata"
          }
        }
      }
    }
  }
}

Expected behavior

It should create some other models that belongs to the jsonview. Like this what happens when you return an List instead of a Pagable object.

{
  "openapi": "3.1.0",
  "info": {
    "title": "OpenAPI definition",
    "version": "v0"
  },
  "servers": [
    {
      "url": "http://localhost:8092",
      "description": "Generated server url"
    }
  ],
  "paths": {
    "/world": {
      "get": {
        "tags": [
          "hello-controller"
        ],
        "operationId": "getWorldPaged",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index (0..N)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "The size of the page to be returned",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HelloWorld_World"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/hello": {
      "get": {
        "tags": [
          "hello-controller"
        ],
        "operationId": "getHelloPaged",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index (0..N)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "The size of the page to be returned",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HelloWorld_Hello"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HelloWorld_World": {
        "type": "object",
        "properties": {
          "world": {
            "type": "string"
          }
        }
      },
      "HelloWorld_Hello": {
        "type": "object",
        "properties": {
          "hello": {
            "type": "string"
          }
        }
      }
    }
  }
}

Please ask if you have any further questions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions