swagger-api / swagger-codegen-generators Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
I previously asked this question on stackoverflow.
I am writing automated end-to-end tests for an API that makes use of Swagger. I would like to reuse the model classes (and the example property values in particular) in my tests as payload of some HTTP requests to our API. Reusing the annotated model classes allows me to test whether the examples are still up to date and to give a head start to developers writing new tests. However, I found it is unnecessarily complicated to write a generic method to create a model object filled with the example property values from the @APIModelProperty
annotations.
This seems like a fairly common use case to me. Therefore, I am considering to contribute to swagger to enable this functionality. Am I welcome to submit a PR for this problem? My suggested approach is as follows:
io.swagger.codegen.examples.ExampleGenerator
similar to resolveModelToExample
, which returns a POJO that will generate the example JSON when serializedresolveModelToExample
There is an error with dependency classes from guava. But instead fixing it with maven dependency declaration, let's take this chance to migrate that logic to Java 8.
PREREQUISITE:
With swagger-api/swagger-codegen#7492 and swagger-api/swagger-codegen#7556 a new library option was introduced for the java client generator.
This work needs to be migrated to be used with version 3.0.0
of codegen.
I have started to work on it on a separated branch restassured. It is included in the last RC release I made for our company last week. I will submit a pull request when the blocking PR is merged.
Is there a way to add other JSON annotations to a class?
Let's say I wanted all classes to have
@JsonIgnoreProperties(ignoreUnknown = true)
I'm envisioning that I would add to the config file with the class to import and then annotation..
JavaJAXRSSpecServerCodegen processOpts() method calls super.processOpts() which has already set apiPackage and modelPackage before JavaJAXRSSpecServerCodegen writes them again to
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";
This overwrites any additioinalProperty set for these variables.
Hello!
I believe I have found a bug in DefaultCodegen
. I would like to use HTTP authentication using the "Bearer" authentication scheme, like the Swagger Docs suggest I have the following OpenAPI security scheme declaration:
components:
securitySchemes:
bearer:
type: http
scheme: bearer
What I expect is that the generated client should set a corresponding HTTP header:
Authorization: Bearer <USER_PROVIDED_TOKEN_HERE>
However, the generated client initializes HTTP authentication that requires username and password, which are then encoded together. This prevents users from specifying their token in a natural way. The output in my case (Java) looks as follows:
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
authentications.put("bearer", new HttpBasicAuth());
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
Note that setUsername
as well as setPassword
do not make sense in my use-case and that setApiKey
, setApiKeyPrefix
, and setAccessToken
will throw RuntimeException
s because no authentication of the respective type is configured.
I think that the mistake lies in the two lines in DefaultCodegen
that I have highlighted above. This code checks whether HTTP authentication should be used, and then, independently of the authentication scheme to be used, sets a flag that will trigger generation of basic authentication. This results in code incompatible with bearer authentication. For more background on HTTP authentication schemes, please refer to this article on MDN.
To fix this bug, I believe that a more granular treatment of HTTP authentication is needed. One branch should go for basic authentication as is done now always, but at least one more branch to forward credentials for other schemes is required. This could be done by adding another implementation of io.swagger.client.auth.Authentication
or modifying io.swagger.client.auth.ApiKeyAuth
slightly to account for HTTP authentication schemes, similar to setApiKeyPrefix
.
I could implement the described fix, once you give your OK.
As a workaround, one may use:
components:
securitySchemes:
# Workaround for https://github.com/swagger-api/swagger-codegen-generators/issues/113
bearer:
type: apiKey
in: header
name: Authorization
In conjunction with some adjustments in the user code, for the Java case:
client.setApiKeyPrefix("Bearer");
client.setApiKey("<USER_PROVIDED_TOKEN_HERE>");
For the moment the only integration tests we have are located in the swagger-codegen
repo. There are a lot of *.sh
and *.bat
scripts under bin/
that calls the cli
tool and that generate code in samples/
. Then each generated project is tested. This is great and this effort should continue.
At swagger-codegen-generators
level we need something else between unit tests and the mentioned integration tests. We need to see the impact of a change in the Codegen
(and in the abstract Codegen
like DefaultCodegenConfig
) in the generated code (for each supported framework).
I propose following approach:
We create a Unit Test class (say GenerateSampleTest
) containing one test case (say generateXxxxTest()
) for each kind of generator we want to support (by genarator I mean Codegen class & library combination. For example for JavaClientCodegen
we need multiple test cases to support the different libraries). This calls the generator programatically (no dependency on cli
tool) and generate code in a subfolder of the samples/
folder at the root of the swagger-codegen-generators
repository (similar to the integration test suite in the swagger-codegen
repo).
The idea is that after a change, the GenerateSampleTest
Test will be called (I guess everybody runs a mvn verify
locally). The idea is to control the changes in the samples/
folder and to commit them inside the same pull request.
The spec used as input should be in the openapi: 3.0.1
format. It should also be extended when new buggy pattern are detected to be as complete as possible. Over the last weeks, following issues were fixed for special cases:
The input spec used by the GenerateSampleTest
should contains one example of each cases described in theses bug reports. Yes it will be a monster spec, but this is the point. For more realistic example, we have the integration test suite in swagger-codegen
.
At CI (Travis) level, the idea is to break the build if after the execution of the Maven Build (that will run the GenerateSampleTest
) the samples/
folder contains changes that are not committed. This way we ensure that the folder is updated with each Pull Request.
Before I start to implement it, I would like to know what you think.
cc: @HugoMario, @webron, @wing328
A non declared argument, allowableValues
, is placed for OAS 3.0 annotation @Parameter
The issue is related to an array of string set with a enum for a parameter named status
, an example of this is /pet/findByStatus:
path from petstore sample :
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
produces:
- application/xml
- application/json
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: true
type: array
items:
type: string
enum:
- available
- pending
- sold
default: available
collectionFormat: csv
responses:
'200':
description: successful operation
schema:
type: array
items:
$ref: '#/definitions/Pet'
'400':
description: Invalid status value
security:
- petstore_auth:
- 'write:pets'
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l jaxrs-cxf-cdi -o output -DhideGenerationTimestamp=true
Keeping in mind that it does not matter that definition is in OAS 2 format since Swagger Codegen v3
supports it.
So the generated output with error on PetApi.java
class is:
public Response findPetsByStatus( @NotNull @Parameter(description = "Status values that need to be considered for filter",required=true, allowableValues="available, pending, sold") @QueryParam("status") List<String> status) {
return delegate.findPetsByStatus(status, securityContext);
}
when we try to build generated code with mvn package
command we got:
[ERROR] /Users/hugomercado/GitHub/swagger-codegen/samples/server/petstore/jaxrs-cxf-cdi/src/gen/java/io/swagger/api/PetApi.java:[106,111] cannot find symbol
[ERROR] symbol: method allowableValues()
[ERROR] location: @interface io.swagger.v3.oas.annotations.Parameter
Hi,
Server side code generator for openapi: 3.0.0 in not generating code for spring. There is no file which is being downloaded nor any error being thrown.
When generating models using either the Java or Inflector languages, properties are duplicated in each subclass.
For instance when using the Inflector language, this piece in the YAML:
components:
schemas:
Capability:
type: object
properties:
prop:
type: string
CapabilitySubType:
allOf:
- $ref: '#/components/schemas/Capability'
- properties:
differentProp:
type: string
will produce these classes:
public class Capability {
@JsonProperty("prop")
private String prop = null;
/**
**/
public Capability prop(String prop) {
this.prop = prop;
return this;
}
@ApiModelProperty(value = "")
@JsonProperty("prop")
public String getProp() {
return prop;
}
public void setProp(String prop) {
this.prop = prop;
}
public class CapabilitySubType extends Capability {
@JsonProperty("prop")
private String prop = null;
@JsonProperty("differentProp")
private String differentProp = null;
/**
**/
public CapabilitySubType prop(String prop) {
this.prop = prop;
return this;
}
@ApiModelProperty(value = "")
@JsonProperty("prop")
public String getProp() {
return prop;
}
public void setProp(String prop) {
this.prop = prop;
}
/**
**/
public CapabilitySubType differentProp(String differentProp) {
this.differentProp = differentProp;
return this;
}
@ApiModelProperty(value = "")
@JsonProperty("differentProp")
public String getDifferentProp() {
return differentProp;
}
public void setDifferentProp(String differentProp) {
this.differentProp = differentProp;
}
It seems to me that since CapabilitySubType
extends Capability
it should use the prop
field/getter/setter from its parent class without recreating prop
in it's own private scope.
Is this a known issue or something on the roadmap?
Thanks!
I was working on #51 and to ensure that my change will not break anything, I have checked the current status of the java generators in swagger-codegen
repository in the samples/
folder on the 3.0.0 branch. I use version 1.0.0-SNAPSHOT
of the swagger-codegen-generators
generators.
The scripts needs to be fixed and the examples needs to be generated again.
I will report here what needs to be addressed.
Symptom: omit info > contact > email (or url)
- This seems to validate in the swagger editor but if you generate an html client, it will be autofilled with helloreverb.com.
Affected templates: HTML and HTML2. Dynamic HTML I think is fine.
You can try reproducing it by comparing the output with and without lines 6-8 in this file
When minimum and maximum is set for a property of type number in OAS, it does not show in the generated code.
In the DefaultCodegenConfig - CodegenProperty minimum and maximum is not set for NumberSchema.
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: An paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
text/plain:
schema:
type: string
components:
schemas:
Pet:
type: object
properties:
Total_Pet:
type: number
minimum: 0
maximum: 10
The snippet below from an OpenAPI document shows a parameter in path and request body whose schemas are both references to an enum StuffType
:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
termsOfService: http://swagger.io/terms/
contact:
name: Swagger API Team
email: [email protected]
url: http://swagger.io
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: http://petstore.swagger.io/api
paths:
/stuff/{stuffType}:
post:
tags:
- 'stuff'
description: "Do some stuff"
operationId: "doStuff"
parameters:
- name: "stuffType"
in: "path"
required: true
schema:
$ref: '#/components/schemas/StuffType'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StuffType'
responses:
'200':
description: 'A response'
content:
application/json:
schema:
$ref: '#/components/schemas/StuffType'
components:
schemas:
StuffType:
type: string
enum:
- A_1
- B_1
- D_2
This is the method generated by jaxrs-spec
:
@POST
@Path("/{stuffType}")
@ApiOperation(value = "", notes = "Do some stuff", response = StuffType.class, tags={ "stuff" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "A response", response = StuffType.class)
})
public Response doStuff(@PathParam("stuffType") StuffType stuffType,@Valid String body) {
return Response.ok().entity("magic!").build();
}
While the generated method uses StuffType
as the type for the path parameter, String
is used as the type for body
.
In OpenAPI specification we define the content type before describing the schema.
My response is declared as follows:
responses:
'200':
description: OK
content:
text/javascript:
schema:
$ref: '#/components/schemas/Response'
But after generating my Java client, if I try to consume the API, I receive an exception:
Content type "text/javascript; charset=utf-8" is not supported for type: class com.example.model.Response
Checking the source code, this is the block that generates the exception
\\ ApiClient.java#deserialize()
String contentType = response.headers().get("Content-Type");
if (contentType == null) {
// ensuring a default content type
contentType = "application/json";
}
if (isJsonMime(contentType)) {
return json.deserialize(respBody, returnType);
} else if (returnType.equals(String.class)) {
// Expecting string, return the raw response body.
return (T) respBody;
} else {
throw new ApiException(
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
response.code(),
response.headers().toMultimap(),
respBody);
}
Since we are consuming a third party API and we can't edit the returned content-type, is there a way to handle different content types or should we provide a custom implementation of the Client?
As of now, Swagger Codegen always uses old (1.5.x
) Swagger annotations, @ApiModel
/ @ApiModelProperty
to decorate model classes, even if the input specification comes in OAS 3.0.x format. I believe it would make sense to use the Swagger 2.0.x @Schema
annotations in this case since it corresponds to OAS 3.0.x specification and has different, richer set of attributes.
It could be done either on advisory level, for example using configOptions
(in case of swagger-codegen-maven-plugin
):
<configOptions>
<oas3>true</oas3>
</configOptions>
Or, if feasible, could be done automatically in case Swagger Codegen recognizes that specification corresponds to OAS 3.0.x. Here is the example of the model class:
@Schema(description = "...") // Before: @ApiModel
public class Person {
@JsonProperty("email")
private String email = null;
public Person email(String email) {
this.email = email;
return this;
}
@Schema(description = "...", example = "...") // Before: @ApiModelProperty
public String getEmail() {
return email;
}
}
@webron would appreciate your opinion, if the issue makes sense, I will submit the PR for it.
Thank you!
This feature was implemented with #43 and removed with #54.
The framework is providing two ways to set values:
additionalProperties
map.From a usage point of view, setting a value in one way or an other one should create no difference:
Setter:
JavaClientCodegen config = new io.swagger.codegen.languages.java.JavaClientCodegen();
config.setArtifactId("my-artifact-id");
config.setModelPackage("xyz.company.example.model");
Map:
JavaClientCodegen config = new io.swagger.codegen.languages.java.JavaClientCodegen();
config.additionalProperties().put(CodegenConstants.ARTIFACT_ID, "my-artifact-id")
config.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.company.example.model");
In my opinion, using setters is more natural, but both way are offered and needs to be supported.
Because of this dual way to set value, the Codegen
classes need to conciliate both way and ensure that everything is consistent. This is done in processOpts()
. The values need to be available in the templates (using {{artifactId}}
or {{modelPacakge}}
from the previous example), no matter if they were set the map or the setter way.
To solve this issue, the commit aa9e90b pushed with PR #54 needs to be reverted.
Hi!
2.x implementation sets up adapters based on discriminator. The new one does not.
Is it made on purpose?
Though the specification 3.0 itself is released, ecosystem not involved rapidly enough. I just spend a couple of days to create a 3.0 specification for our 100+ api endpoints, then sadly learned that python, swift code generators are not implemented yet.
Before our generators catch up, is it a practical solution to first create a 3.0 -> 2.0 generator?
Hey! I create new issue, because previous issue was closed.
There are {{#hasMore}} attribute was still in some places:
Thank!
In the OpenAPI Specification there is no limitation on the name of the properties in an object schema.
Some heuristic is used to determined the name of the corresponding member in the java Object.
The problem is that lorem
, $_lorem
, _lorem
, lorem$
are all mapped to a member field called member
3.0.0-rc0
openapi: 3.0.1
info:
title: A dummy title
version: 1.0.0
paths:
/my/endpoint:
get:
summary: Returns an object
operationId: getMyObject
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: "#/components/schemas/Dummy"
components:
schemas:
Dummy:
type: object
properties:
'lorem':
type: string
‘$_lorem':
type: string
mvn compile
POM configuration:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.0-rc0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${oas-spec}</inputSpec>
<language>java</language>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-generators</artifactId>
<version>1.0.0-rc0</version>
</dependency>
</dependencies>
</plugin>
public class Dummy {
@SerializedName("lorem")
private String lorem = null;
@SerializedName("$_lorem")
private String lorem = null;
// …
}
This might be a corner case, but for our use case we can not generate the java client for our API with this code generator.
public class Dummy {
@SerializedName("lorem")
private String lorem = null;
@SerializedName("$_lorem")
private String $_lorem = null;
// …
}
I intend to implement both the server and client side for akka-http, soonish, as I have time available. I'm aware of the various Scala support in the 2.0 project but none of it is based on the right technologies for our purposes. I will, however, endeavor to layer it so that Scala based code generation can be done in multiple ways. That is, I will factor in the request in swagger-codegen issue 3812. This ticket will effectively provide a 3.0 implementation for swagger-codegen issue 5900 .
I welcome all discussion here about combining efforts to create server and client generators that support reactive programming. Mostly they both need to be asynchronous non-blocking systems that implement backflow via Akka Streams. If I'm duplicating work (haven't seen it yet), please let me know!
A properties in a request body with content type application/x-www-form-urlencoded
or multipart/formData
should be added on collection:
List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
from DefaultCodegenConfig
class. In order to be present in each template that use them.
Rebuild and push the latest swagger-codegen-generator
in order to fix java.lang.AbstractMethodError in the integration tests
The “custom arguments” logic was changed by @HugoMario with following commits:
Now the swagger-codegen-cli
(version 3.0.0-SNAPSHOT
) is broken:
Exception in thread "main" java.lang.AbstractMethodError: io.swagger.codegen.languages.java.JavaClientCodegen.readLanguageArguments()Ljava/util/List;
at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:94)
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=2g; support was removed in 8.0
I think that this is due to a build order problem.
When the commit in repo swagger-codegen
was pushed, swagger-codegen-cli
was build, embedding an old version of swagger-codegen-generators
.
I think that the latest swagger-codegen-generator-1.0.0-SNPASHOT.jar
was not correctly built and pushed. Probably because the swagger-codegen
build was not finished.
Now when you build swagger-codegen
repo, the build is OK, but when the integration tests are executed (the *.sh
scripts), you get the AbstractMethodError
exception.
Something is wrong with the build.
There are cyclic dependencies between the 2 builds of the swagger-codegen
repo and the swagger-codegen-generator
repo.
io.swagger:swagger-codegen-generator:1.0.0-SNAPSHOT
needs io.swagger:swagger-codegen:3.0.0-SNAPSHOT
from the swagger-codegen
repository.
And io.swagger:swagger-codegen-cli:3.0.0-SNAPSHOT
includes io.swagger:swagger-codegen-generator:1.0.0-SNAPSHOT
from the swagger-codegen-generators
repository.
When API breaking changes are pushed on the same time in the 2 repos, the continuous integration build is complicated.
I have some trouble with a OpenAPI spec containing a oneOf
switch. (from documentation Data Models (Schemas) > oneOf, anyOf, allOf, not)
When I try to generate the java client, I get an error caused by a null pointer Exception (version 1.0.0-SNAPSHOT
).
openapi: 3.0.1
info:
title: oneOf test
version: '1.0'
servers:
- url: 'http://localhost:8000/'
paths:
/pets:
patch:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
responses:
'200':
description: Updated
components:
schemas:
Pet:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
Dog:
type: object
properties:
bark:
type: boolean
breed:
type: string
enum: [Dingo, Husky, Retriever, Shepherd]
Cat:
type: object
properties:
hunts:
type: boolean
age:
type: integer
Exception in thread "main" java.lang.RuntimeException: Could not process model 'Pet'.Please make sure that your schema is correct!
at io.swagger.codegen.DefaultGenerator.generateModels(DefaultGenerator.java:361)
at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:726)
at <my code>
Caused by: java.lang.NullPointerException
at io.swagger.codegen.languages.DefaultCodegenConfig.fromModel(DefaultCodegenConfig.java:1210)
at io.swagger.codegen.languages.java.AbstractJavaCodegen.fromModel(AbstractJavaCodegen.java:845)
at io.swagger.codegen.DefaultGenerator.processModels(DefaultGenerator.java:959)
at io.swagger.codegen.DefaultGenerator.generateModels(DefaultGenerator.java:356)
... 3 more
When instead of having a Pet
schema in the components, the composed-schema is inlined in the requestBody (as in the example from the docs), then the generator works.
openapi: 3.0.1
info:
title: oneOf test
version: '1.0'
servers:
- url: 'http://localhost:8000/'
paths:
/pets:
patch:
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
responses:
'200':
description: Updated
components:
schemas:
Dog:
type: object
properties:
bark:
type: boolean
breed:
type: string
enum: [Dingo, Husky, Retriever, Shepherd]
Cat:
type: object
properties:
hunts:
type: boolean
age:
type: integer
environment:
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T09:58:13+02:00)
Maven home: C:\Users\sfg\.m2\wrapper\dists\apache-maven-3.5.2-bin\28qa8v9e2mq69covern8vmdkj0\apache-maven-3.5.2
Java version: 9.0.4, vendor: Oracle Corporation
Java home: c:\progs\jdk-9.0.4
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
plugin config:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.0-rc0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>src/main/swagger/swagger.json</inputSpec>
<language>java</language>
<output>target/generated-sources</output>
<configOptions>
<sourceFolder>swagger</sourceFolder>
<generateApiTests>true</generateApiTests>
<dateLibrary>joda</dateLibrary>
<modelPackage>de.model</modelPackage>
<apiPackage>de.api</apiPackage>
<invokerPackage>de.invoker</invokerPackage>
<library>jersey2</library>
<withXml>true</withXml>
</configOptions>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-generators</artifactId>
<version>1.0.0-rc0</version>
</dependency>
</dependencies>
</plugin>
error:
java.lang.RuntimeException: Could not generate api file for 'Default'
at io.swagger.codegen.DefaultGenerator.generateApis (DefaultGenerator.java:525)
at io.swagger.codegen.DefaultGenerator.generate (DefaultGenerator.java:725)
at io.swagger.codegen.plugin.CodeGenMojo.execute (CodeGenMojo.java:534)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:309)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:194)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:107)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:955)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:564)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:564)
at org.apache.maven.wrapper.BootstrapMainStarter.start (BootstrapMainStarter.java:39)
at org.apache.maven.wrapper.WrapperExecutor.execute (WrapperExecutor.java:122)
at org.apache.maven.wrapper.MavenWrapperMain.main (MavenWrapperMain.java:55)
Caused by: java.io.FileNotFoundException: /v2/Java/\libraries\jersey2\api.mustache
at com.github.jknack.handlebars.io.URLTemplateLoader.sourceAt (URLTemplateLoader.java:70)
at com.github.jknack.handlebars.Handlebars.compile (Handlebars.java:357)
at com.github.jknack.handlebars.Handlebars.compile (Handlebars.java:343)
at io.swagger.codegen.DefaultGenerator.getHandlebars (DefaultGenerator.java:1013)
at io.swagger.codegen.DefaultGenerator.processTemplateToFile (DefaultGenerator.java:738)
at io.swagger.codegen.DefaultGenerator.generateApis (DefaultGenerator.java:484)
at io.swagger.codegen.DefaultGenerator.generate (DefaultGenerator.java:725)
at io.swagger.codegen.plugin.CodeGenMojo.execute (CodeGenMojo.java:534)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:309)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:194)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:107)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:955)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:564)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:564)
at org.apache.maven.wrapper.BootstrapMainStarter.start (BootstrapMainStarter.java:39)
at org.apache.maven.wrapper.WrapperExecutor.execute (WrapperExecutor.java:122)
at org.apache.maven.wrapper.MavenWrapperMain.main (MavenWrapperMain.java:55)
It looks like a problem with File.separator.
Let's try to generate Java client for this OpenAPI definition file:
openapi: 3.0.0
paths:
/test:
get:
tags:
- Test
summary: Test
parameters:
- $ref: '#/components/parameters/IDList'
responses:
'200':
description: Test
components:
parameters:
IDList:
name: ids
description: |
List of ids.
in: query
style: form
schema:
type: array
items:
type: string
The current templates:
{{#is this 'query-param'}}@retrofit.http.Query("{{baseName}}") {{#if collectionFormat}}{{#is this 'collection-format-multi'}}{{{dataType}}}{{/is}}{{#isNot this 'collection-format-multi'}}{{{collectionFormat.toUpperCase}}}Params{{/isNot}}{{else}}{{{dataType}}}{{/if}} {{paramName}}{{/is}}
{{#is this 'query-param'}}@retrofit2.http.Query("{{baseName}}") {{#if collectionFormat}}{{#is this 'collection-format-multi'}}{{{dataType}}}{{/is}}{{#isNot this 'collection-format-multi'}}{{{collectionFormat.toUpperCase}}}Params{{/isNot}}{{else}}{{{dataType}}}{{/if}} {{paramName}}{{/is}}
generates the foloowing output:
@retrofit2.http.Query("ids") Params ids
Wich produces the following errot at complie time:
Error:(42, 34) java: cannot find symbol
symbol: class Params
location: interface io.swagger.client.api.TestApi
CSVParams or List should be a better dataType
My pom.xml is the folowing:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${swagger-codegen.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>src/main/resources/openapi/openapi.yaml</inputSpec>
<language>java</language>
<library>retrofit2</library>
<configOptions>
<dateLibrary>java8</dateLibrary>
</configOptions>
<generateApiTests>false</generateApiTests>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-generators</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
Now that custom arguments have been implemented we can remove the system properties and use custom arguments instead.
Hello,
Please merge the he pull request swagger-api/swagger-codegen#7984.
In templates, there is a use of variables 'useNgPackagr' and 'useOldNgPackagr' but never set in TypeScriptAngularClientCodegen.java.
There is also a 'ng-package.mustache' who is never used.
When using powershell to generate source code (using maven) we get the following error while building a Model:
[ERROR]
java.lang.RuntimeException: Could not generate model 'BaseProfile'
at io.swagger.codegen.DefaultGenerator.generateModels (DefaultGenerator.java:407)
at io.swagger.codegen.DefaultGenerator.generate (DefaultGenerator.java:722)
at io.swagger.codegen.plugin.CodeGenMojo.execute (CodeGenMojo.java:534)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:309)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:194)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:107)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:955)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: java.io.FileNotFoundException: /v2/Java/\model.mustache
at com.github.jknack.handlebars.io.URLTemplateLoader.sourceAt (URLTemplateLoader.java:70)
at com.github.jknack.handlebars.Handlebars.compile (Handlebars.java:357)
at com.github.jknack.handlebars.Handlebars.compile (Handlebars.java:343)
at io.swagger.codegen.DefaultGenerator.getHandlebars (DefaultGenerator.java:1013)
at io.swagger.codegen.DefaultGenerator.processTemplateToFile (DefaultGenerator.java:738)
at io.swagger.codegen.DefaultGenerator.generateModels (DefaultGenerator.java:394)
at io.swagger.codegen.DefaultGenerator.generate (DefaultGenerator.java:722)
at io.swagger.codegen.plugin.CodeGenMojo.execute (CodeGenMojo.java:534)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:309)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:194)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:107)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:955)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Using linux the model is created correctly.
3.0.0-rc0
mvn generate-sources
Maybe paths should use File.separator to be cross-compatible ?
The recent builds fail because the new 3.0.0-SNAPSHOT of swagger-api/swagger-codegen (io/swagger/swagger-codegen/3.0.0-SNAPSHOT/) is not getting pushed to the maven repo.
As you can see here: https://oss.sonatype.org/content/repositories/snapshots/io/swagger/swagger-codegen/3.0.0-SNAPSHOT/
To fix this you have to enable the "push to maven" feature again:
The swagger-codegen is renamed to "swagger-codegen-project" in 3.0.0. Maybe you have to adjust this in the pom.xml.
Hello,
At the end of the template, one '}' is missing between {{/operation}} and {{/operations}}.
{{/operation}}
}
{{/operations}}
So I saw that 3.0.0 will use this repository for codegen generators. Version 2.3.x introduced some major breaking changes to the produced code. While most of these changes made sense, some of them are - in my opinion - bad choices.
I would like to use the chance that releasing 3.0.0 is, to start a discussion on providing a better code generator for Golang.
I'd like to start with some things that I think are really well done in the new 2.3.x release:
http.Client
context.Context
in API callsI think there are also some issues.
if localVarHttpResponse.StatusCode >= 300 {
bodyBytes, _ := ioutil.ReadAll(localVarHttpResponse.Body)
return localVarHttpResponse, reportError("Status: %v, Body: %s", localVarHttpResponse.Status, bodyBytes)
}
map[string]interface{}
that needs, for example, a body
key.The second limitation is especially painful from an API point of view as type assertions are necessary to decode the payload, and the API is not very developer friendly in the context of Go. In real-world use it looks something like this:
CreateResource(context.Context, map[string]interface{}{"body": &SomeStruct{}})
I propse that instead, a type is used to solve this, for example:
type CreateResourceParameters struct {
Body *SomeStruct
Path ...
Query ...
}
This would make the process of passing down request parameters much more usable and less error prone.
Let me know what you think.
Opening this issue to migrate typescript-angular templates to the new format.
Using Spring codegen on a schema with a discriminator property populates the @JsonTypeInfo
annotation with the Discriminator
class represented as a string, instead of the propertyName itself.
For example, this schema:
Example:
type: object
required:
- baseType
discriminator:
propertyName: baseType
properties:
baseType:
type: string
otherProp:
type: string
will generate this class:
/**
* Example
*/
@Validated
@javax.annotation.Generated(value = "io.swagger.codegen.languages.java.SpringCodegen", date = "2018-06-18T16:55:52.608-04:00[America/New_York]")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "Discriminator{propertyName='baseType', mapping=null}", visible = true )
@JsonSubTypes({
})
public class Example {
@JsonProperty("baseType")
private String baseType = null;
@JsonProperty("otherProp")
private String otherProp = null;
public Example baseType(String baseType) {
this.baseType = baseType;
return this;
}
/**
* Get baseType
* @return baseType
**/
@ApiModelProperty(required = true, value = "")
@NotNull
public String getBaseType() {
return baseType;
}
public void setBaseType(String baseType) {
this.baseType = baseType;
}
public Example otherProp(String otherProp) {
this.otherProp = otherProp;
return this;
}
/**
* Get otherProp
* @return otherProp
**/
@ApiModelProperty(value = "")
public String getOtherProp() {
return otherProp;
}
public void setOtherProp(String otherProp) {
this.otherProp = otherProp;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Example example = (Example) o;
return Objects.equals(this.baseType, example.baseType) &&
Objects.equals(this.otherProp, example.otherProp);
}
@Override
public int hashCode() {
return Objects.hash(baseType, otherProp);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Example {\n");
sb.append(" baseType: ").append(toIndentedString(baseType)).append("\n");
sb.append(" otherProp: ").append(toIndentedString(otherProp)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
The point of interest here is with the line:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "Discriminator{propertyName='baseType', mapping=null}", visible = true )
which should read:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "baseType", visible = true )
PREREQUISITE: following PR needs to be merged:
JaxRS generators were introduced here with #29 (and with the follow up tasks #38, #36 and #39). JaxRS Client CFX generator was introduce with #47. JaxRS examples in the samples/
folder are going to be updated with swagger-api/swagger-codegen#7854.
As indicated in the help description message, the mentioned generators still generate code for Swagger v2:
WORK IN PROGRESS: generated code depends from Swagger v2 libraries
One example of the impact:
When you run mvn clean package jetty:run
inside the samples/server/petstore/jaxrs/jersey2/
folder and then call http://localhost:8080/v2/swagger.yaml
, you obtain:
swagger: "2.0"
info:
...
host: "petstore.swagger.io:80"
basePath: "/v2"
tags:
...
schemes:
- "http"
paths:
/another-fake/dummy:
patch:
...
/fake/outer/boolean:
post:
tags:
- "fake"
summary: ""
description: "Test serialization of outer boolean types"
operationId: "fakeOuterBooleanSerialize"
consumes:
- "*/*"
produces:
- "*/*"
parameters:
- in: "body"
name: "body"
description: "Input boolean as post body"
required: false
schema:
type: "boolean"
responses:
200:
description: "Output boolean"
schema:
type: "boolean"
/fake/outer/composite:
post:
...
/fake/outer/number:
...
The big next step for the JaxRS generators will be to generate code that will be using Swagger v3 artefacts. Then the page to call to get the spec will be http://localhost:8080/v2/openapi.yaml
I did not look at all the details yet, but I think the main point is to replace:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
<version>1.5.15</version>
</dependency>
With:
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
The swagger-samples
repository on branch 2.0
contains valuable examples that already works with Swagger v3. See: https://github.com/swagger-api/swagger-samples/tree/2.0/
I will work on this as soon as the blocking PR are merged.
AbstractJavaJAXRSServerCodegen always logs a needless warning-level MalformedURLException for a valid OAS 2.0 YAML, because according to the OAS 2.0 specification for basePath: "The value MUST start with a leading slash (/)", which can never be a valid URL and will thus always throw MalformedURLException.
[WARNING] Not valid URL: /v1/dt
java.net.MalformedURLException: no protocol: /v1/dt
at java.net.URL.(URL.java:593)
at java.net.URL.(URL.java:490)
at java.net.URL.(URL.java:439)
at io.swagger.codegen.utils.URLPathUtil.getServerURL(URLPathUtil.java:30)
at io.swagger.codegen.languages.java.AbstractJavaJAXRSServerCodegen.preprocessOpenAPI(AbstractJavaJAXRSServerCodegen.java:92)
at io.swagger.codegen.DefaultGenerator.configureGeneratorProperties(DefaultGenerator.java:201)
at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:722)
at io.swagger.codegen.plugin.CodeGenMojo.execute(CodeGenMojo.java:534)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
When running codegen on schemas using the Spring language, boolean getter method names contain the "is" prefix twice.
For example, this model:
Example:
type: object
properties:
myprop:
type: boolean
default: True
Will generate this class:
public class Example {
@JsonProperty("myprop")
private Boolean myprop = true;
public Example myprop(Boolean myprop) {
this.myprop = myprop;
return this;
}
/**
* Get myprop
* @return myprop
**/
@ApiModelProperty(value = "")
public Boolean isisMyprop() {
return myprop;
}
public void setMyprop(Boolean myprop) {
this.myprop = myprop;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Example example = (Example) o;
return Objects.equals(this.myprop, example.myprop);
}
@Override
public int hashCode() {
return Objects.hash(myprop);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Example {\n");
sb.append(" myprop: ").append(toIndentedString(myprop)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
Notice the isisMyprop()
method, which should be named isMyprop()
.
Any parameter to an operation will have x-is-enum
and x-is-list-container
set on it, regardless of whether or not the parameter actually represents an enum.
The following OpenAPI and swift4
snippets illustrate this:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
termsOfService: http://swagger.io/terms/
contact:
name: Swagger API Team
email: [email protected]
url: http://swagger.io
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: http://petstore.swagger.io/api
paths:
/pets/{id}:
get:
description: Returns a user based on a single ID, if the user does not have access to the pet
operationId: find pet by id
parameters:
- name: id
in: path
description: ID of pet to fetch
required: true
schema:
type: integer
format: int64
responses:
'200':
description: pet response
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
/stuff/{stuffType}:
delete:
tags:
- 'stuff'
description: "Delete the stuff"
operationId: "deleteStuff"
parameters:
- name: "stuffType"
in: "path"
required: true
schema:
type: 'string'
enum:
- ASD
- FGH
- JKL
responses:
'200':
description: 'A response'
Generated code:
/**
* enum for parameter _id
*/
public enum _findPetById: Int64 {
}
/**
- parameter _id: (path) ID of pet to fetch
- parameter completion: completion handler to receive the data and the error objects
*/
open class func findPetById(_id: _findPetById, completion: @escaping ((_ data: Pet?,_ error: Error?) -> Void)) {
findPetByIdWithRequestBuilder(_id: _id).execute { (response, error) -> Void in
completion(response?.body, error)
}
}
/**
* enum for parameter stuffType
*/
public enum StuffType_deleteStuff: String {
case asd = "ASD"
case fgh = "FGH"
case jkl = "JKL"
}
/**
- parameter stuffType: (path)
- parameter completion: completion handler to receive the data and the error objects
*/
open class func deleteStuff(stuffType: StuffType_deleteStuff, completion: @escaping ((_ data: Void?,_ error: Error?) -> Void)) {
deleteStuffWithRequestBuilder(stuffType: stuffType).execute { (response, error) -> Void in
completion(response?.body, error)
}
}
While the generated code for deleteStuff
has the correct inline enum, findPetById
generates a nonsense blank enum instead.
In swagger 2.0 schemata produces was a top level field with mime-types. In OpenApi 3.0.0 schemata media-types are used for this purpose and they are located differently, as key for MediaType-Objects in the content map. That means that if multiple responses are described, the same media-type can be used as a key in the response content maps.
However, when I try to use this new feature of OpenAPI 3.0.0, my generated java client code comes out faulty. Using this project to generate java code for the following schema-fragment
responses:
'200':
description: pet response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
results in the following code
final String[] localVarAccepts = {
"application/json""application/json"
};
because hasMore
is incorrectly not added to the 'last content in the first response'.
Moreover, application/json appears twice in the codegenOperation.produces
ArrayList because while each response yields a Set
of media-type keys, those sets are combined into a List
at the codegenOperation.produces
level.
We're getting build success in maven but there is an error because an expected file (mvnw) is missed.
travis_time:end:0b887d28:start=1517960823002986545,finish=1517960852615714515,duration=29612727970
�[0Ktravis_fold:end:install
�[0Ktravis_time:start:19493319
�[0K$ ./mvnw clean verify
/home/travis/.travis/job_stages: line 57: ./mvnw: No such file or directory
travis_time:end:19493319:start=1517960852623041063,finish=1517960852630086436,duration=7045373
�[0K
�[31;1mThe command "./mvnw clean verify" exited with 127.�[0m
Done. Your build exited with 1.
Looking at https://oss.sonatype.org/content/repositories/snapshots/io/swagger/swagger-codegen-generators/1.0.0-SNAPSHOT/, the latest is 1/28/2018.
Is this accurate?
I with a spec like this:
'/pet/{petId}':
post:
tags:
- pet
summary: Updates a pet in the store with form data
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
name:
type: string
description: Updated name of the pet
status:
type: string
description: Updated status of the pet
responses:
'405':
description: Invalid input
content: {}
Complete spec here: petstore.json
Java generator.
IS:
Corresponding method in io.swagger.client.api.PetApi
:
public void updatePetWithForm(String petId, Object body) throws ApiException
SHOULD BE:
Corresponding method in io.swagger.client.api.PetApi
:
public void updatePetWithForm(String petId, Body body) throws ApiException
With this import line:
import io.swagger.client.model.Body;
And this class io.swagger.client.model.Body
:
public class Body {
@SerializedName("name")
private String name = null;
@SerializedName("status")
private String status = null;
//...
}
I guess this has also something to do with following LOG statement:
[main] WARN io.swagger.codegen.languages.DefaultCodegenConfig - String to be sanitized is null. Default to Object
In Mustache, it was possible to set custom delimiters. Example (source):
{{ default_tags }}
{{=<% %>=}}
<% erb_style_tags %>
<%={{ }}=%>
{{ default_tags_again }}
Explanation:
{{
and }}
are used.<%
and %>
should be used instead of {{
and }}
.{{
and }}
should be set instead of <%
and %>
.This do not seems to work with handlebars. This stackoverflow question propose an alternative to escape {
and }
in handlebar: {{"{"}}
and {{"}"}}
.
Example in swagger templates (example from /modules/swagger-codegen/src/main/htmlDocs2/sample_js.mustache
).
Mustache:
...some text.. {{=< >=}}{<&dataType>}<={{ }}=> .. and more .......
But this does'nt work with handlebar java:
...some text.. {{"{"}}{{&dataType}}{{"}"}} .. and more .......
Also, I am not sure that the leading '/' will work on all platforms.
Pushed by 3f3d552
@HugoMario maybe take a look?
Spring codegen doesn't add set a @JsonTypeId
annotation on the field used as the discriminator property, causing duplications of this field when serializing to JSON.
NOTE: This example assumes issue #103 as fixed.
Using these schemas:
Example:
type: object
required:
- baseType
discriminator:
propertyName: baseType
properties:
baseType:
type: string
otherProp:
type: string
SubExample:
allOf:
- $ref: '#/components/schemas/Example'
- type: object
Will generate this Example
class (truncated for illustration):
/**
* Example
*/
@Validated
@javax.annotation.Generated(value = "io.swagger.codegen.languages.java.SpringCodegen", date = "2018-06-18T16:55:52.608-04:00[America/New_York]")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "baseType", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = SubExample.class, name = "SubExample"),
})
public class Example {
@JsonProperty("baseType")
private String baseType = null;
@JsonProperty("otherProp")
private String otherProp = null;
}
When trying to serialize an instance of this class as JSON, the discriminator field will be included twice, like so:
{
"baseType":"SubExample",
"baseType":"SubExample",
"otherProp":"some value"
}
The @JsonTypeId
annotation can be used to fix this. By declaring the annotation on the same field used as the discriminator, like so:
public class Example {
@JsonProperty("baseType")
@JsonTypeId
private String baseType = null;
@JsonProperty("otherProp")
private String otherProp = null;
An instance of this class would properly serialize to JSON as:
{
"baseType":"SubExample",
"otherProp":"some value"
}
Should the location of the $ref affect the behavior of building classes?
In this first case, the class TransactionRequestSale extends TransactionRequest (as you would expect). The fields Amount and Type are created with getters/setters
TransactionRequestSale:
description: A Sale request.
allOf:
- $ref: '#/components/schemas/TransactionRequest'
- type: object
properties:
Type:
type: string
Amount:
type: integer
but if the $ref is after the type, then TransactionRequest is used instead of the object, rather than extending the class. (ie the TransactionRequestSale class is created, but rather than the Amount and Type fields, it uses the fields from TransactionRequest)
TransactionRequestSale:
description: A Sale request.
allOf:
- type: object
properties:
Type:
type: string
Amount:
type: integer`
- $ref: '#/components/schemas/TransactionRequest
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.