Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameter and response body mapping #1089

Merged
merged 7 commits into from
Jun 30, 2023
Merged

Conversation

andriy-dmytruk
Copy link
Contributor

These changes are to allow the use of custom types for parameters and response bodies to utilize all Micronaut capabilities for code simplification.

Parameters mapping

As an example, if we add the following parameter mappings:

[
  {name: "page", location: "QUERY", mappedType: "io.micronaut.data.model.Pageable"},
  {name: "size", location: "QUERY", mappedType: "io.micronaut.data.model.Pageable"},
  {name: "sortOrder", location: "QUERY", mappedType: "io.micronaut.data.model.Pageable"},
]

micronaut Pageable will be used for page, size or sortOrder headers:

    @Get("/sendPageQuery")
    @Produces({"application/json"})
    Mono<String> sendPageQuery(
        @NotNull
        Pageable pageable
    );

instead of each header being a separate parameter:

    @Get("/sendPageQuery")
    @Produces({"application/json"})
    Mono<String> sendPageQuery(
        @HeaderParam
        Integer page,
        @HeaderParam
        Integer size,
        @Headerparam
        String sortOrder
    );

The spec in this case is :

operations:
  /sendPageQuery:
    get:
      operationId: sendPageQuery
      tags: [ parameters ]
      description: A method that takes page query as its argument
      parameters:
        - $ref: '#/parameters/PageQueryParam'
        - $ref: '#/parameters/PageSizeQueryParam'
        - $ref: '#/parameters/PageSortQueryParam'
      responses:
        200:
          description: Success
          schema:
            type: string
parameters:
  PageQueryParam:
    name: page
    in: query
    type: integer
    minimum: 0
    default: 0
    description: The page number to retrieve starting from 0.
  PageSizeQueryParam:
    name: size
    in: query
    type: integer
    minimum: 1
    default: 10
    description: The number of items per page.
  PageSortQueryParam:
    name: sortOrder
    in: query
    type: string
    description: |
      Parameter describing the sort. Allows specifying the sorting direction using the keywords {@code asc} and
      {@code desc} after each property. For example, {@code "sort=name,desc,&sort=age"} will sort by name in descending
      order and age in ascending.

Similarly to the example above, custom types can be created with TypedRequestArgumentBinder implementations. Parameters can be ignored by setting the mappedType to null, as some parameters may be consumed inside interceptors or filters.

Response body mapping

The body mapping works in a similar way, but changes the return type of operation. Since server can only return header parameters, the mapping is done based on them.

For example, if we add the following body mapping:

{headerName: "Last-Modified", mappedBodyType: "io.micronaut.openapi.test.dated.DatedResponse"}

the operation would be created as (if a Last-Modified header is specified):

    @Get("/getDatedSimpleModel")
    @Produces({"application/json"})
    Mono<DatedResponse<SimpleModel>> getDatedSimpleModel();

The custom DatedResponse object then would need a MessageBodyWriter implementation and include the required header.

The specification in the case above:

operations:
  /getDatedSimpleModel:
    get:
      operationId: getDatedSimpleModel
      tags: [ responseBody ]
      description: A method to get a simple model with last-modified header
      responses:
        200:
          description: Success
          headers:
            Last-Modified: *Last-Modified-header
          schema:
            $ref: '#/definitions/SimpleModel'
x-headers:
  LastModifiedHeader: &Last-Modified-header
    name: Last-Modified
    type: string
    format: date-time
    description: The last time an entity returned with the response was modified.

Note

We can make this interface available in gradle/maven plugins or keep available for extension generators only.

}

private static List<Map<String, String>> parseListOfMaps(String string) {
System.out.println("json: " + string);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
System.out.println("json: " + string);

@sonarcloud
Copy link

sonarcloud bot commented Jun 29, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 8 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants