Skip to content
This repository was archived by the owner on Mar 16, 2025. It is now read-only.

Releases: openapi-processor/openapi-processor-core

2021.4.2

20 Jun 16:42
Compare
Choose a tag to compare

#72, missing @NotNull bean-validation with allOf composition

fixed missing required constraints of the composed object of an allOf schema list. The required constraints of the source schemas were ignored causing the missing @NotNull annotation.

the fix is based on a pull request by @Tucos

2021.4.1

12 Jun 08:02
Compare
Choose a tag to compare

openapi-processor/openapi-processor-spring#128, broken import list for allOf schema

fixed the imports list of a composed allOf schema. The processor did not properly walk the property tree of the merged schema and it generated a model class with missing imports.

2021.4

30 May 15:55
Compare
Choose a tag to compare

#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 ...);

#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;
    ...
}

#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.

#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

#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:
        ...

#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)

2021.3.1

25 Apr 15:40
Compare
Choose a tag to compare

openapi-processor/openapi-processor-spring#126

fixed duplicate media types in the produces parameter of the mapping annotation.

dependency updates

updated swagger parser to 2.0.25 (was 2.0.24)

2021.3

14 Mar 09:09
Compare
Choose a tag to compare

javadoc improvements

#56, generate endpoint javadoc of an OpenAPI operation from summary & description (previously only description was used) using the following format:

/**
 * OpenAPI summary (plain text)
 * 
 * OpenAPI description (common mark)
 */
@GetMapping("/foo")
Foo getFoo();

#57, generate pojo javadoc from description fields.

/** schema description (common mark) */
public class Foo {

    /** property description (common mark) */
    @JsonProperty("foobar")
    private String foobar;

    public String getFoobar() {
        return foobar;
    }

    public void setFoobar(String foobar) {
        this.foobar = foobar;
    }

}

The processor generates multi line javadoc comments but the code formatter may flatten them into single line comments as in the example above.

openapi-processor/openapi-processor-spring#124, $ref-chain

A $ref-chain, like the one below, (a $ref that points to another $ref and so on..., possibly spanning multiple files) lost the original/correct name of the schema and generated wrong class names. The processor does now properly resolve the chain with the correct name.

As an example for the chain below, the processor selects User for the User schema (correct). Previously it selected user or something else depending on the chain (wrong):

openapi.yaml (excerpt):

paths:
  '/user':
    $ref: ./apis/user.v1.yaml#/paths/~1user

apis/user.v1.yaml (excerpt):

paths:
  '/user':
    post:
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

components:
  schemas:
    User:
      $ref: ../models/user.model.v1.yaml

models/user.model.v1.yaml (excerpt):

type: object
properties:
  ...

improved names of inline schemas (maybe breaking)

internally the processor assigns names to inline schemas (request body & response). For example the following response would get the name QueryResponse200. It is now QueryGetResponse200. Difference is that it contains the http method.

...
paths:
  /query:
    get:
      responses:
        '200':
           ...

In theory it is possible to map the schema using its generated inline name (named schema mappings are preferred). Since the inline name has changed such a mapping needs to be updated.

updated dependencies

  • updated openapi4j parser to 1.0.7 (was 1.0.4)

2021.2

27 Feb 21:44
Compare
Choose a tag to compare

#45, support for mapping OpenAPI nullable properties to jackson-databind-nullable.

This is useful to implement a json merge patch api that needs to know if a property was not set at all or explicitly set to "null" ("null" means to clear the property value).

For example, the /foo api endpoint uses the following schema as request body

...

components:
  schemas:

    Foo:
      description: a Foo
      type: object
      properties:
        bar:
          nullable: true
          type: string

Normally the processor would generate a simple pojo with a String property. By adding a null mapping for the /foo endpoint (this does work only on the endpoint level, a global null mapping gets ignored):

openapi-processor-mapping: v2

map:
  paths:
    /foo:
      null: org.openapitools.jackson.nullable.JsonNullable
      # with initialization:
      # null: org.openapitools.jackson.nullable.JsonNullable = JsonNullable.undefined()

it will generate the following code:

import com.fasterxml.jackson.annotation.JsonProperty;
import org.openapitools.jackson.nullable.JsonNullable;

public class Foo {

    @JsonProperty("bar")
    private JsonNullable<String> bar;
    // with initialization:
    // private JsonNullable<String> bar = JsonNullable.undefined();

    public JsonNullable<String> getBar() {
        return bar;
    }

    public void setBar(JsonNullable<String> bar) {
        this.bar = bar;
    }

}

#55, endpoint mapping by http method.

It is now possible to add mappings that apply only to a specific http method. Motivation for this is to limit the mapping only to the place where it is needed. Http method mappings have priority over other mappings. In general, the most specific mapping is used.

Here are a few examples of possible http endpoint mappings:

openapi-processor-mapping: v2

map:

 paths:
   /foo:

     # normal endpoint mappings apply to all http methods (behaves exactly as before)
     types:
       - type: Foo => java.util.Collection

     # endpoint http method mappings apply only the specified http method
     get:
       result: org.springframework.http.ResponseEntity

     post:
       parameters:
          - add: request => javax.servlet.http.HttpServletRequest

     patch:
       null: org.openapitools.jackson.nullable.JsonNullable = JsonNullable.undefined()

The structure follows the OpenAPI, i.e. the http methods (or OpenAPI operations) are properties of the endpoint path.

An http method mapping allows the same mappings as the endpoint mapping without http method, i.e. exclude, result, single, multi, null, types, parameters and responses (see the mapping json schema).

The last example is using the new null mapping that may only be interesting for the PATCH http method because there is no need for nullable properties for GET or PUT. Note that it is not possible to use different null mappings (or one http mapping with null and one without) on the same model schema. The processor generates only a single class for model schemas and with two different and ambiguous mappings the result is (currently) undefined. It is recommended to use two different schemas if the null mapping should only apply to a single method.

#58, endpoint parameters with openapi4j parser

Parameters at the endpoint/path level (which are used for all operations) were ignored with the openapi4j parser.

2021.1

13 Feb 17:38
Compare
Choose a tag to compare
  • jars are published on maven central (was jcenter).

  • (beta) generation of javadoc from OpenAPI descriptions. It is off by default, to enable set the javadoc option to true:

    openapi-processor-mapping: v2
    
    options:
      javadoc: true
    
  • (experimental) additional add parameter annotation. It is possible to add one additional annotation to a parameter add mapping.

    Motivation is the micronaut @RequestAttribute annotation. It is required to bind a parameter to an attribute of the request which is typically created in a filter:

    openapi-processor-mapping: v2
    
    map:
      paths:
        /api/process:
          parameters:
            - add: requestId => io.micronaut.http.annotation.RequestAttribute("requestId") java.lang.String
    

    The parameters of the annotation are "passed through" as string.

  • #50, improved detection of used schemas for model class generation. It now detects schemas that are only use by a type mapping:

    openapi-processor-mapping: v2
    
    map:
      types:
        - type: FooPage => org.springframework.data.domain.Page<generated.model.Foo>
    

    Because of the mapping the processor didn't look at anything that was part (property of) of FooPage. If Foo was only referenced by FooPage no model class was generated for Foo.

  • #51, handle schemas without properties (i.e. do not crash), e.g.

    type: object
    additionalProperties: { }
    
  • #1, better error reporting if the openapi.yaml does not exist

  • updated swagger parser to 2.0.24 (was 2.0.23)

2020.4 (1.4.0)

09 Dec 22:35
Compare
Choose a tag to compare
  • #34, report a formatting error including the failing source code

  • #35, using tags like test_api & test-api at the same time would override one interface. Both tags result in the same java interface name TestApi ( '_' is (usually) not used in interface names and - is not a valid java identifier char).

    The processor will now merge endpoints with tags like this into the same interface

  • #39, added json schema for the mapping.yaml. Some IDEs (e.g. Intellij IDEA) use it to provide editing support. Thanks to @schlagi123 for providing the initial version

  • #41, the _ character was lost when converting enum value names to valid java identifiers. For example an enum value FOO_FOO was converted to FOOFOO. The underscore is now preserved for enum values.

  • #43, first step of allOf support. allOf of multiple object schemas will create a model class with all properties of the individual items.

  • #44, fixed generation of @NotNull bean validation annotation. It is now based on the required property instead of the nullable property

  • #48, a type-less schema would crash the processor. It has now minimal handling (more or less ignoring it) so it does not crash anymore.

      allOf:
        - readOnly: true                       # type-less schema
        - $ref: '#/components/schemas/Foo'     # does not matter if it is $ref
  • updated swagger parser to 2.0.23 (was 2.0.21)

v1.3.0

07 Nov 18:01
Compare
Choose a tag to compare
  • #30, preserve the "?" generic parameter of a mapping and pass it on to the generated api, e.g. a mapping like

    map:
      paths:
        /foo:
          parameters:
            - add: foo => io.openapiprocessor.Foo<?>

    does now generate

    void foo(Foo<?> foo);

    instead of

    void foo(Foo foo);
  • openapi-processor/openapi-processor-spring#119, primitive type could match a primitive type with format mapping, e.g. with the mapping

    openapi-processor-spring: v2
    
    map:
      types:
        - type: string:binary => io.openapiprocessor.Foo
    

    it was possible that a primitive string was mapped to io.openapiprocessor.Foo instead of java.lang.String

  • a ref loop with array items caused a NullPointerException

1.2.1

13 Oct 06:05
Compare
Choose a tag to compare
  • the internal representation of an empty response (ie. without any response data) leaked to the generated code. Visible by a produces = {"?"} in the mapping annotation and an Object return type of the endpoint.