Skip to content

Suggest a feature to adjust indentation when parsing the @Operation annotation in Kotlin. #2446

Closed
@e-build

Description

@e-build

Is your feature request related to a problem? Please describe.

I would like to propose a feature based on the problems I encountered while gradually introducing Kotlin in a Java project that was using springdoc.

  • A clear and concise description of what the problem is.
    • The project has been maintained by recording a detailed description of the HTTP API in the 'description' attribute of the @Operation annotation. For example:

        @Operation(
            summary = "Store single item inquiry",
            description = """
            Search for a specific store.
            - [jira ticket](...link_url...)
            - If you pass storeId to the URL path, store information corresponding to the ID will be returned.
      
            ### Custom exception case
            | Http Status | Error Code  | Error Message | Error Data | Remark   |
            |-------------|-------------|--------------|------------|-----------|
            | 403         | NO_PERMISSION       |This request is only available to administrators.  |            |           |
            | 400         | STORE_NOT_FOUND       |Store not found.   |            |           |
            | 400         | STORE_WAS_DELETED       |This store has been deleted.  |            |           |
            """
        )
        @GetMapping("/stores/{storeId}")
        public ResponseEntity<GetStoreResponse> getStore(
            @PathVariable String storeId
        ){
            ...
        }

      The description of the generated openapi.json file and the actual rendered markdown of swagger-ui are as follows.

      Search for a specific store.\n- [jira ticket](...link_url...)\n\
      - If you pass storeId to the URL path, store information corresponding to\
      \ the ID will be returned.\n\n#### Custom exception case\n| Http Status |\
      \ Error Code  | Error Message | Error Data | Remark   |\n|-------------|-------------|--------------|------------|-----------|\n\
      | 403         | NO_PERMISSION       |This request is only available to administrators.\
      \  |            |           |\n| 400         | STORE_NOT_FOUND       |Store\
      \ not found.   |            |           |\n| 400         | STORE_WAS_DELETED\
      \       |This store has been deleted.  |            |           |\n
      
      java-swager-ui
    • However, if you write the description the same way in Kotlin, it will not render the markdown in the same way. The markdown of the generated openapi.json file and the actual rendered swagger-ui in Kotlin is as follows.

      \n        Search for a specific store.\n        - [jira ticket](...link_url...)\n\
      \        - If you pass storeId to the URL path, store information corresponding\
      \ to the ID will be returned.\n        \n        #### Custom exception case\n\
      \        | Http Status | Error Code  | Error Message | Error Data | Remark \
      \  |\n        |-------------|-------------|--------------|------------|-----------|\n\
      \        | 403         | NO_PERMISSION       |This request is only available\
      \ to administrators.  |            |           |\n        | 400         | STORE_NOT_FOUND\
      \       |Store not found.   |            |           |\n        | 400      \
      \   | STORE_WAS_DELETED       |This store has been deleted.  |            |\
      \           |\n        
      
      kotlin-swagger-ui

Describe the solution you'd like

  • A clear and concise description of what you want to happen.
    • I know this is a difference due to the specifications for 'multiline string' between Java and Kotlin. Java adjusts indentation to match the closing three double quote, but Kotlin does not.
      So, if you forcefully modify Kotlin's API so that there is no leading space as follows, you can check that the markdown is rendered normally.
          @Operation(
              summary = "Store single item inquiry",
              description = """
      Search for a specific store.
      - [jira ticket](...link_url...)
      - If you pass storeId to the URL path, store information corresponding to the ID will be returned.
      
      #### Custom exception case
      | Http Status | Error Code  | Error Message | Error Data | Remark   |
      |-------------|-------------|--------------|------------|-----------|
      | 403         | NO_PERMISSION       |This request is only available to administrators.  |            |           |
      | 400         | STORE_NOT_FOUND       |Store not found.   |            |           |
      | 400         | STORE_WAS_DELETED       |This store has been deleted.  |            |           |
      """
          )
          @GetMapping("/stores/{storeId}")
          fun getStores(): ResponseEntity<GetStoreResponse> {
              return GetStoreListResponse.of(
                  ...
              )
          }
      However, it is a very cumbersome task to do this for all of the approximately 3,000 HTTP APIs that exist in the current project. Above all, the appearance of the Kotlin API modified in the above manner is quite unattractive.
    • In Kotlin, as in Java, I want it to be rendered in markdown format rather than as a code block, without having to force the indentation to be removed. The way I propose to solve this problem is as follows:
    • Add springdoc properties such as springdoc.swagger-ui.remove-kotlin-indent.
    • When parsing the description in OperationService.parse() of the springdoc-openapi-starter-common dependency, if the above property is true, indented spaces are deleted from the value of the description.

I had great fun looking at the code. As I suggested the issue, I would like to contribute to springdoc by implementing the feature myself. If there is any part of what I wrote that is difficult to understand, please give me feedback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions