Skip to content

2021.4

Choose a tag to compare

@hauner hauner released this 23 Dec 09:51
· 2057 commits to main since this release

copied from openapi-processor-core

openapi-processor/openapi-processor-core#62, validate mapping with mapping json schema

Sometimes the processor generates wrong or unexpected code that seems to ignore a setting from the mapping.yaml. Usually this is caused by an error in the mapping.yaml, e.g. because of a wrong indentation.

To ease the pain of finding the error in the mapping.yaml it is validated with the mapping json schema. The validation step provides warnings only, i.e. the processor will still run.

#63, support pattern constraint

The OpenAPI pattern constraint translates to a @Pattern bean validation annotation. For example a parameter like this

# OpenAPI
...
parameters:
  - in: query
     name: anything
     schema:
       type: string
       pattern: .*\.\\
       description: string with regex constraint

will add a corresponding @Pattern(...) annotation to the method parameter:

// java
import javax.validation.constraints.Pattern;

  ...
  void getWithPattern(@Pattern(".*\\.\\\\") ... String ...);

openapi-processor/openapi-processor-core#64, add @Valid annotation on collections

Collections with object items are annotated with @Valid annotation to enable validation of the items in the collection.

Like this for array:

// java
public class Foo {

    @Valid
    ...
    private Bar[] bars;
    ...
}

or like this for Collection, Set or List:

// java
public class Foo {
    ...
    private Collection<@Valid Bar> bars;
    ...
}

openapi-processor/openapi-processor-core#65, automatically add a suffix to generated model pojos and enums

it is now possible to configure a suffix that the processor will automatically append to the name of model pojo classes and enum classes.

# mapping.yaml
openapi-processor-mapping: v2

options:
  package-name: io.openapiprocessor
  model-name-suffix: Resource  # or Dto or ....

The model-name-suffix option is optional (string value, by default it is empty (i.e. it is disabled)).

The suffix helps to

  • avoid duplicate class names in generated code and normal code
  • makes it easier to recognize which role or in which context a class is used. Is it a data transfer class or is it a domain class?
  • keeps the suffix "noise" out of the OpenAPI description

If a schema name from the OpenAPI description already ends with the model-name-suffix, the processor will not append the suffix. This allows to migrate an existing api with a suffix in the API to model-name-suffix step by step.

Applying the above mapping to the following api

# OpenAPI 
paths:
  /foo:
    get:
      responses:
        '200':
          description: the foo result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Foo' # <1>

components:
  schemas:

    Foo:
      type: object
      properties:
        nested:
          $ref: '#/components/schemas/BarResource' # <1>

    BarResource:
      type: object
      properties:
        prop:
          type: string

will create the classes

// java

// interface
public interface Api {

    @Mapping("/foo")
    FooResource getFoo(); // <2>

}

// pojos
public class FooResource { // <2>

    // ...

    @JsonProperty("nested")
    private BarResource nested;

    // ...
}

public class BarResource { // <3>

    // ...
}
  • <1> a schema name without suffix
  • <2> the class name of the Foo schema got the configured Resource suffix
  • <3> the class name of the BarResource is identical to the original schema name. Since the existing suffix is equal to model-name-suffix it is ignored. Otherwise, This prevents funny class names like BarResourceResource.

openapi-processor/openapi-processor-core#66, parameters in javadoc were not written as java identifiers

the original parameter name from the OpenAPI description was used to create the javadoc @param comment which could be an invalid java identifier (e.g. foo-bar).

/**
 ...
 * @param foo-bar a foo bar 
 */

The javadoc is now generated with the same valid java identifier used in the source code:

/**
 ...
 * @param fooBar a foo bar 
 */

extract multi-part encoding

the parsing step extracts the encoding/contentType of a multipart content. This allows a processor to consider the encoding content type when selecting the annotation for the part.

openapi-processor-spring uses this to select between @RequestPart and @RequestParam. If an econding/contentType is available it will use @RequestPart, if no econding/contentType is available it will use @RequestParam.

openapi: 3.0.2
info:
  title: params-request-body-multipart
  version: 1.0.0

paths:
  /multipart:
    post:
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                json:
                  type: object
                  properties:
                    foo:
                      type: string
                    bar:
                      type: string
            encoding:
              file:
                contentType: application/octet-stream
              json:
                contentType: application/json          
      responses:
        '204':
          description: empty

openapi-processor/openapi-processor-core#67, pojos only used in a multipart response are not generated

improved detection of used schemas for model class generation. It now properly detects schemas that are only use by a multipart response.

Since the "parts" are conerted into single parameters, there is no need for a request body pojo that contains all parts. Filtering the all parts pojo did drop the single part pojos.

method level exclude did override endpoint level exclude

If the mapping.yaml did have a method level endpoint mapping with exclude: false (the default if not set) it did override the exclude: true at the endpoint level.

# mapping.yaml
map:
  paths:
    /endpoint:
      exclude: true

      get:
        ...

openapi-processor/openapi-processor-core#59, operationId did override method names with media types

for example, having the following response

paths:
  /foo:
    get:
      # operationId: get_foo_operation
      responses:
        '200':
          description: json or plain text result
          content:
            application/json:
                schema:
                  $ref: '#/components/schemas/Foo'
            text/plain:
                schema:
                  type: string

the processor generated

    @Mapping("/foo")
    Foo getFooOperation();

    @Mapping("/foo")
    String getFooOperation();

instead of

    @Mapping("/foo")
    Foo getFooOperationApplicationJson();

    @Mapping("/foo")
    String getFooOperationTextPlain();

dependency updates

updated swagger parser to 2.0.26 (was 2.0.25)