Git Product home page Git Product logo

openapi-processor-core's Introduction

openapi-processor-core's People

Contributors

hauner avatar tucos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

openapi-processor-core's Issues

support OpenAPI "deprecated" property

properties

in:

  schemas:
    Foo:
      type: object
      properties:
        bar:
          type: string
          deprecated: true  

out:

class Foo {

    @Deprecated
    @JsonProperty("bar")
    private String bar;

     //.....
}

endpoints

in:

paths:
  /foo:
    get:
      # ....
      deprecated: true

out:

interface Foo {

    @Deprecated
    @GetMapping(path = "/foo")
    void getFoo();
    // ....
}

code formatter breaks with java 16

running with java 16 throws:

java.lang.IllegalAccessError: class com.google.googlejavaformat.java.JavaInput (in unnamed module @0x2064d52f) cannot access class com.sun.tools.javac.parser.Tokens$TokenKind (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.parser to unnamed module @0x2064d52f

pojos only used in a multipart response are not generated

another missing class issue, caused by trying to filter the request body of a multipart request in ApiConverter.createMultipartParameter.

Since the "parts" are split into single parameters, there is no need for request body pojo that contains all parts. Unfortunately that looses the reference to the part pojos.

endpoint mapping by http method

currently the endpoint mappings are applied to all http methods of a single endpoint:

openapi-processor-mapping: v2.0
    
map:
  paths:
    /foo:
      parameters:
        - add: request => javax.servlet.http.HttpServletRequest

It should be possible to configure an endpoint mapping only for a specific http method:

openapi-processor-mapping: v2.0
    
map:
  paths:
    /foo:
      get:
        parameters:
          - add: request => javax.servlet.http.HttpServletRequest

bean validation sets wrong @NotNull constraints

  • by default object properties are optional in an OpenAPI description.

  • @NotNullshould be based on the required constraint and not on nullable.

    if foo is required it must be set:

     { foo: "bar" }
    

    if it is not required it may be missing:

     {  }
    
  • nullable means if the property is given it may be null.

    { foo: null }
    

    it is ok even if foo is required: foo is there so the required constraint is fulfilled.

Base path missing

When I describe an API Spec

openapi: 3.0.3
servers:
  - url: 'http://localhost:8080/api'

the base path will be ignored. I can't anything in the documentation.

Mapping to Generated Types with shortcut

Currently I reference in a Mapping a self generated resource:

openapi-processor-mapping: v2
options:
  package-name: de.test.generated
map:
  types:
    - type: UserPageResource => org.springframework.data.domain.Page<de.test.generated.UserResource>

I think it would a nice idea to reference a generated typ directly and not other the java type. e. g:

    - type: UserPageResource => org.springframework.data.domain.Page<UserResource>

or

    - type: UserPageResource => org.springframework.data.domain.Page<*UserResource>

or somthing like that.

`nullable` support for model classes

mapping a json payload to a java class looses the nullable information.

For example the following two payloads will produce the same java object for a model class with a single String property foo:

  • {}
  • {foo: null}

Both will be deserialized to an object with foo = null. No way to know if it was missing or if it was null.

This is a necessary info to implement PATCH with json merge patch:

  • if a property is not set don't change it
  • if it is set to "null", clear the property (set it to null).

This could be implemented by using jackson-databind-nullable.

Because of the additional dependency it should be off by default and it gets enabled by setting a new configuration option.

Windows paths not supported

Working Directory: C:\Users\TEST-USER\dev\code\local\eclipse-workspace\openapi-processor-samples\samples
Gradle user home: C:\Users\TEST-USER.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 6.5.1
Java Home: C:\Program Files\Java\jdk-11.0.8
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: processSpring

Configure project :samples:spring-webflux
Gradle version: 6.5.1

Task :samples:spring-mvc:processSpring FAILED
processing failed!
java.net.MalformedURLException: unknown protocol: c
at java.base/java.net.URL.(URL.java:652)
at java.base/java.net.URL.(URL.java:541)
at java.base/java.net.URL.(URL.java:488)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:237)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:249)
at com.github.hauner.openapi.core.parser.openapi4j.Parser.parse(Parser.groovy:38)
at com.github.hauner.openapi.core.parser.openapi4j.Parser$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at com.github.hauner.openapi.core.parser.Parser.parse(Parser.groovy:47)
at com.github.hauner.openapi.core.parser.Parser$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at com.github.hauner.openapi.spring.processor.SpringProcessor.run(SpringProcessor.groovy:55)
at io.openapiprocessor.api.OpenApiProcessor$run$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at com.github.hauner.openapi.gradle.OpenApiProcessorWorker.run(OpenApiProcessorWorker.groovy:44)
at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:57)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.lambda$execute$0(IsolatedClassloaderWorkerFactory.java:58)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.execute(IsolatedClassloaderWorkerFactory.java:50)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:200)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:834)

FAILURE: Build completed with 1 failures.

1: Task failed with an exception.

  • What went wrong:
    Execution failed for task ':samples:spring-webflux:processSpring'.

A failure occurred while executing com.github.hauner.openapi.gradle.OpenApiProcessorWorker
unknown protocol: c

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    ==============================================================================

BUILD FAILED in 1s
1 actionable tasks: 1 executed

better response type handling

If an api has multiple response content types (success & errors) the java response type of the controller method will be Object to allow return values with different java types.

If the errors are handled by throwing an exception there is no need to have an Object response and the controller method could use the type of the success response to improve readability of the interface.

mapping could be like this, using a globally applied option:

# mapping.yaml
openapi-processor-mapping: v2

options:
  response-type: all    # all (default) or success

or like this, allowing endpoint & endpoint/method configuration:

# mapping.yaml
openapi-processor-mapping: v2

map:
  response-type: all    # all (default) or success

all: consider all response types to select the method return type
success: consider only the success response type, i.e. usually 200

Lost API

If I use the following YAML:

openapi: 3.0.2
info:
  title: name me
  version: 1.0.0

paths:
  /api/test1:
    get:
      summary: Test.
      operationId: test_1
      tags:
        - test_api
      responses:
        200:
          description: Test
 
  /api/test2:
    get:
      summary: Test.
      operationId: test_2
      tags:
        - test-api
      responses:
        200:
          description: Test

The difference of the apis are the tag (test_api and test-api).
One api of the two is lost in the result. I had excepted, that I get...

  • 2 Interfaces,
  • 1 Interface with both apis or
  • an error

But currently one api is lost.

upgrade to openapi4j 1.0

There are test failures with openapi4j 1.0.

org.openapi4j.parser.model.v3.Schema.copy() has no parameters anymore and that seems to break com.github.hauner.openapi.core.parser.openapi4j.RefResolver.

do not crash on allOf with a type-less schema

hitting a schema like this one will crash the processor:

schema:
  type: object
  properties:
    foo:
      allOf:
        - readOnly: true                       # type-less schema
        - $ref: '#/components/schemas/Foo'     # does not matter if it is $ref

It should not crash, even if it does not handle the schema without a type.

marker interface for oneOf?

Is it worth adding a marker interface to the items of oneOf that's used as the type instead of Object?

moved anyOf to #90, one step at a time

parse "?" generic parameter to an explicit object instead of an empty list

passing a HttpRequest to a (Micronaut) controller without providing a body type uses a parameter like this (in kotlin):

request: HttpRequest<*>

the mapping to add the parameter is:

map:
  paths:
    /foo:
      parameters:
        - add: request => io.micronaut.http.HttpRequest<?>

Currently this translates to an empty generic parameter list, i.e. the generated java parameter is just

void foo(HttpRequest request);

this shows a warning in IDEA: Raw use of parameterized class 'HttpRequest'

The kotlin implementation can implement it as

override fun foo(request: HttpRequest<*>)

but it would be nice to generate the java endpoint with generic parameter to remove the warning

void foo(HttpRequest<?> request);

does not generate model class if it is only referenced in a type mapping

Having an openapi description with a model schema that is not directly referenced anymore after considering the mappings, is not generated even if it still referenced by a mapping.

This can happen if the there is a paged response that is mapped to the Spring framework Page class and there is no other endpoint that uses the page content type.

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

The details of the mapped openapi schema (which describes the page response in this case) are not considered anymore. It is replaced by the mapping so there is no need to generate the page content type.

The processor should recognize that the type is used and should generate the type.

Workaround:

a possible workaround is to create a dummy schema under components.schemas that references the missing type.

reverse dependency of core and spring

oap-core was extracted from oap-spring to reuse it in oap-micronaut. Now oap-spring & oap-micronaut depend on oap-core.

since core changes most often it causes new releases for oap-spring & oap-micronaut.

It would be nice to avoid that by converting the framework projects (which seldom change) to something like plugins of core.

validate openapi.yaml

find errors in the openapi.yaml before the processor fails by validating the openapi.yaml with the json schema.

This is easy for a single file openapi.yml files.

Using jackson and json-schema-validator it basically works like this:

    val mapper = ObjectMapper(YAMLFactory())
    val tree = mapper.readTree(apiURL)
    // setup validator to use json schema in yaml format
    val factory = JsonSchemaFactory.Builder()
        .objectMapper(mapper)
        .defaultMetaSchemaURI(JsonMetaSchema.getV4().uri)
        .addMetaSchema(JsonMetaSchema.getV4())
        .build()

    val schema30 = URI("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.yaml")
    val schema = factory.getSchema(schema30)
    val validation = schema.validate(tree)

Unfortunately it doesn't work with an openapi.yaml that $refs into other files. To validate it, all $refd files need to be merged into the openapi.yaml file.

I didn't find any easily usable java code to do this :-(

What it should do:

  • add the file content to components:
    • in a nested x-key
    • in a nested file name based key so it is possible to know where the definitions com from
    • replace $ref to other file with $ref to `components/x-key/file-name#/type

Experimental code seems to work on simple $refs.

Formats not work

I use the following type:

type: string
format: uuid

The generator don't know uuid and the process of generation fails.
My idea is, that in case of missing format the default type will be used (in the example 'string').

Reference parameter not working

With following YAML is valid OpenAPI but the $ref of a parameter not work:

info:
  title: simple query parameters
  version: 1.0.0

paths:
  /query:
    get:
      tags:
        - endpoint
      parameters:
        - $ref: "#/components/parameters/MyParameter"
      responses:
        '200':
          description: plain text response
          content:
            plain/text:
              schema:
                type: string

components:
  parameters:
    MyParameter:
      in: query
      name: foo
      schema:
        type: string```

allow endpoint mapping by http method

currently an endpoint specific mapping applies to all http methods. This limits the usefulness of the endpoint mapping because you don't always need/want the mapping for all http methods.

this applies the mappings to all methods (current behaviour):

openapi-processor-mapping: v2

map:
  paths:
    /foo:
      types:
        - type: from => to

this applies the mappings only to the given http method (new/additional behaviour):

openapi-processor-mapping: v2

map:
  paths:
    /foo:
      get:
        types:
          - type: A => B

      patch:
        types:
          - type: A => C

allOf does not work correctly

Hi,

here my minimal schema:

# openapi yaml
openapi: 3.0.2
info:
  title: simple query parameters
  version: 1.0.0

paths:
  /query:
    get:
      tags:
        - endpoint
      responses:
        '200':
          description: plain text response
          content:
            application/json:
              schema:
                allOf:
                  - type: object
                    properties:
                      prop1:
                        type: string
                  - type: object
                    properties:
                      prop2:
                        type: string

If I run the processor I get the following error message:

processing failed!
com.google.googlejavaformat.java.FormatterException: 13:19: error: '{' expected
	at com.google.googlejavaformat.java.FormatterException.fromJavacDiagnostics(FormatterException.java:50)
	at com.google.googlejavaformat.java.Formatter.format(Formatter.java:152)
	at com.google.googlejavaformat.java.Formatter.getFormatReplacements(Formatter.java:291)
	at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:267)
	at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:233)
	at io.openapiprocessor.core.writer.java.ApiWriter.format(ApiWriter.kt:116)
	at io.openapiprocessor.core.writer.java.ApiWriter.writeDataType(ApiWriter.kt:102)
	at io.openapiprocessor.core.writer.java.ApiWriter.access$writeDataType(ApiWriter.kt:41)
	at io.openapiprocessor.core.writer.java.ApiWriter$writeObjectDataTypes$1.accept(ApiWriter.kt:79)
	at io.openapiprocessor.core.writer.java.ApiWriter$writeObjectDataTypes$1.accept(ApiWriter.kt:41)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at io.openapiprocessor.core.model.Api.forEachObjectDataType(Api.kt:60)
	at io.openapiprocessor.core.writer.java.ApiWriter.writeObjectDataTypes(ApiWriter.kt:76)
	at io.openapiprocessor.core.writer.java.ApiWriter.write(ApiWriter.kt:62)
	at io.openapiprocessor.spring.processor.SpringProcessor.run(SpringProcessor.kt:95)
	at io.openapiprocessor.api.OpenApiProcessor$run$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
	at com.github.hauner.openapi.gradle.OpenApiProcessorWorker.run(OpenApiProcessorWorker.groovy:44)
	at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:57)
	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
	at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
	at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
	at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
	at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.lambda$execute$0(IsolatedClassloaderWorkerFactory.java:58)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
	at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.execute(IsolatedClassloaderWorkerFactory.java:50)
	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:200)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:834)

`operationId` breaks method names with multiple content media types

for example, having the following response

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

the processor will/should normally generate two methods

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

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

if the endpoint has an operationId: get_foo it overrides the method name generation, especially the media-type postfix:

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

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

which does not compile (same erasure getFoo()).

The processor should add the media-type postfix to the operationId if it is set.

Format mapping on primitive type not work

I have the following typ:

UUID:
  type: string

and try to map it to a java UUID type:

map:
  types:
    - type: UUID => java.util.UUID

The result of the generated Interface is, that the UUID typ will generated in a String.

If I change the type of UUID to object, it works correctly. My read is, that mapping for primitive types not work.

broken javadoc parameters

the processor should convert a javadoc parameter to a valid java identifier.

currently it may create javadoc with invalid parameters:

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

which should be

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

modelNameSuffix

Hi,

awesome project, thanks for putting in the hours!

The openapi-generator-maven-plugin has a configuration property called modelNameSuffix which, as the name suggest, allows the user to append a suffix to the generated model classes.

Do you thing such a feature would be valuable in your project as well?

Example

Swagger:

components:
  schemas:
    FooObject:
      type: object
      properties:
        bar:
          type: boolean

Mapping:

openapi-processor-mapping: v2

options:
   package-name: example.gen

   modelNameSuffix: Dto

Would result in the generation of example.gen.model.FooObjectDto.java

resolve non schema $ref's

the openapi4j parser does not automatically resolve $ref's. Schema refs are handled by the DataTypeConverter but there are non-schema refs that need to be resolved.

Get a list of all non schema $refs and handle them. Checked items work.

  • path
  • parameter #23

unwanted method with multiple success responses

an endpoint response definition like this:

responses:
  200:
  content:
    application/json:
      schema:
        type: array
        items:
          type: string
  204:
    description: ...

generates the methods

  getFooApplicationJson()
  getFooInvalid()

getFooInvalid() is an unwanted method caused by the 204 response.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.