I am using the swagger-codegen in my gradle file to generate all the controllers & models using the petstore JSON file as input. Is there a way to include pre-defined responses that can be served up when running the generated server code in tomcat? When running the server code in tomcat locally, I only get an empty response body. I am looking to include predefined example/sample response body like a mock server.
2.2.1.
https://gist.github.com/elizabetht/3cd961dae529089eaff789d04d382ad5
language = 'spring'
inputFile = file('src/main/resources/swagger.json')
configFile = file('src/main/resources/config.json')
@elizabetht looks like the Spring templates do not include any response example at the moment.
swagger-codegen|master⚡ ⇒ grep -R -i "example}}" modules/swagger-codegen/src/main/resources/JavaSpring/
modules/swagger-codegen/src/main/resources/JavaSpring//pojo.mustache: @ApiModelProperty({{#example}}example = "{{example}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}")
(only POJO template contains examples defined in the spec)
May I know if you've time to contribute the enhancement? I can show you some good starting points.
@wing328: yes please let me know. I can follow your help.
To clarify, what I am looking for is to start up a tomcat with the war created using spring swagger code gen and get a predefined response when someone hits the endpoint from swagger. Now, I am able to startup tomcat with the war compiled using the generated files but getting an empty response when I hit the endpoint from swagger. The idea is for UI developers to go on with their development using this predefined response while the API services team is working on the actual implementation.
@elizabetht thanks for offering help to add the example support.
We can use the the following mustache tags to add examples in the auto-generated code:
{{#examples}}
{{contentType}} // there should be a if-block to check content type
{{example}} // the example (string) can then be used as a response
{{/examples}}
You can add -DdebugOperations=true to inspect the examples defined in the spec. These values will be used by the mustache templates, e.g.
"imports" : [ "Pet" ],
"examples" : [ {
"contentType" : "application/xml",
"example" : "<Pet>\n <id>123456789</id>\n <name>doggie</name>\n <photoUrls>\n <photoUrls>aeiou</photoUrls>\n </photoUrls>\n <tags>\n </tags>\n <status>aeiou</status>\n</Pet>"
}, {
"contentType" : "application/json",
"example" : "[ {\n \"photoUrls\" : [ \"aeiou\" ],\n \"name\" : \"doggie\",\n \"id\" : 0,\n \"category\" : {\n \"name\" : \"aeiou\",\n \"id\" : 6\n },\n \"tags\" : [ {\n \"name\" : \"aeiou\",\n \"id\" : 1\n } ],\n \"status\" : \"available\"\n} ]"
} ],
The Spring-related templates can be found in https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/JavaSpring
If you need more information, please let me know.
(btw, stable release v2.2.2 was released about a month ago)
@wing328 I am thinking these changes to go in apiController.mustache file? Or where you thinking elsewhere? Please let me know.
Also, let me know which branch I should use as base to send a PR? 2.3.0?
Also, let me know which branch I should use as base to send a PR? 2.3.0?
Current master please. 2.3.0 is for breaking changes.
I am thinking these changes to go in apiController.mustache file? Or where you thinking elsewhere? Please let me know
apiController.mustache seems a good starting point. (disclaimer: not an expert in Java spring)
@wing328 As we discussed, I used objectMapper to read value from the string and convert it to the object without having to change the signature of the generated methods to string. This works fine when I specify just one contentType example, say application/json. When I include both the examples, one for application/json and one for application/xml, the mustache template generates code twice.
Say in my swagger.json, I had the following valid block (swagger spec does not allow examples to be an array)
"examples": {
"application/json": "[ {\n \"photoUrls\" : [ \"aeiou\" ],\n \"name\" : \"doggie\",\n \"id\" : 0,\n \"category\" : {\n \"name\" : \"aeiou\",\n \"id\" : 6\n },\n \"tags\" : [ {\n \"name\" : \"aeiou\",\n \"id\" : 1\n } ],\n \"status\" : \"available\"\n} ]",
"application/xml": "<Pet>\n <id>123456789</id>\n <name>doggie</name>\n <photoUrls>\n <photoUrls>aeiou</photoUrls>\n </photoUrls>\n <tags>\n </tags>\n <status>aeiou</status>\n</Pet>"
}
The PetApiController generated has two return blocks (notice one for each contentType)
ObjectMapper objectMapper = new ObjectMapper();
return new ResponseEntity<List<Pet>>(objectMapper.readValue("[ {\n \"photoUrls\" : [ \"aeiou\" ],\n \"name\" : \"doggie\",\n \"id\" : 0,\n \"category\" : {\n \"name\" : \"aeiou\",\n \"id\" : 6\n },\n \"tags\" : [ {\n \"name\" : \"aeiou\",\n \"id\" : 1\n } ],\n \"status\" : \"available\"\n} ]",List.class), HttpStatus.OK);
ObjectMapper objectMapper = new ObjectMapper();
return new ResponseEntity<List<Pet>>(objectMapper.readValue("<Pet>\n <id>123456789</id>\n <name>doggie</name>\n <photoUrls>\n <photoUrls>aeiou</photoUrls>\n </photoUrls>\n <tags>\n </tags>\n <status>aeiou</status>\n</Pet>",List.class), HttpStatus.OK);
Could you help on how to generate this code once?
Also, when I do not specify examples in swagger.json, the default examples are taken - which is fine. But it creates code like the following and produces compilation errors. Any thoughts?
return new ResponseEntity<List<Pet>>(objectMapper.readValue(<Pet>
<id>123456789</id>
<name>doggie</name>
<photoUrls>
<photoUrls>aeiou</photoUrls>
</photoUrls>
<tags>
</tags>
<status>aeiou</status>
</Pet>,List.class), HttpStatus.OK);
ObjectMapper objectMapper = new ObjectMapper();
return new ResponseEntity<List<Pet>>(objectMapper.readValue([ {
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 0,
"category" : {
"name" : "aeiou",
"id" : 6
},
"tags" : [ {
"name" : "aeiou",
"id" : 1
} ],
"status" : "available"
} ],List.class), HttpStatus.OK);
@elizabetht I fixed a couple of issues: https://github.com/swagger-api/swagger-codegen/compare/master...wing328:elizabetht-issue-5310?expand=1
There are 2 remaining issues:
1) if ("application/json".equals("")) { //TODO need to compare HTTP request "Accept" needs to be fixed by replacing "" with the "Accept" in the HTTP request. Any idea how to obtain that in Spring?
2) we will need to escape double quote. I've a solution in mind so I'll give it a try tomorrow unless someone has a working solution to escape double quote.
@wing328 you can get the Accept header by adding a @RequestHeader("Accept") String accept param to the method
@wing328 @cbornet Any thoughts on how to escape the new line characters that are present in the example?
@wing328 I used if ("{{{contentType}}}".contains(accept)) { because accept comes with "application/json;charset=UTF-8" and equals won't exactly match.
@cbornet thanks for the tips.
I've pushed some fixes. Please review via https://github.com/swagger-api/swagger-codegen/compare/master...wing328:elizabetht-issue-5310?expand=1
I used if ("{{{contentType}}}".contains(accept)) { because accept comes with "application/json;charset=UTF-8"
@elizabetht Later we will need to do a case-insensitive contains instead as MIME type are case insensitive
Also, the ObjectMapper should be injected (at least in Spring Boot) or at least built from the Jackson2ObjectMapperBuilder bean.
@wing328 Pulled in your changes - with your lambda functions for escaping double quotes & line breaks, I am able to compile and see the example output when running my war. Are you saying we should use isJsonMime or something along those lines?
@elizabetht @cbornet let's merge what we've so far into master and work on those enhancements later.
Are you saying we should use isJsonMime or something along those lines?
I thought isJsonMime would be useful but seems like the auto-generated code can still function properly without it. Later if there are valid use cases to create isJsonMime, we'll reconsider.
@cbornet for the enhancement you mentioned, please open a new issue for tracking.
@elizabetht for any additional enhancements, please open a new issue.
@cbornet the enhancements actually change the method signature for Spring Boot client as well and resulting in the following errors:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project swagger-petstore-spring-cloud: Compilation failure: Compilation failure:
[ERROR] /Users/williamcheng/Code/swagger-api/swagger-codegen/samples/client/petstore/spring-cloud/src/test/java/io/swagger/api/UserApiTest.java:[28,15] method createUser in interface io.swagger.api.UserApi cannot be applied to given types;
[ERROR] required: io.swagger.model.User,java.lang.String
[ERROR] found: io.swagger.model.User
[ERROR] reason: actual and formal argument lists differ in length
[ERROR] /Users/williamcheng/Code/swagger-api/swagger-codegen/samples/client/petstore/spring-cloud/src/test/java/io/swagger/api/UserApiTest.java:[30,30] method getUserByName in interface io.swagger.api.UserApi cannot be applied to given types;
[ERROR] required: java.lang.String,java.lang.String
[ERROR] found: java.lang.String
[ERROR] reason: actual and formal argument lists differ in length
[ERROR] /Users/williamcheng/Code/swagger-api/swagger-codegen/samples/client/petstore/spring-cloud/src/test/java/io/swagger/api/UserApiTest.java:[41,15] method createUsersWithArrayInput in interface io.swagger.api.UserApi cannot be applied to given types;
For client, shall we omit the accept parameter?
@wing328 @cbornet I created issue #5413 to track the enhancement that @cbornet suggested and have a fix. Please review it and let me know your comments. Thanks!
@wing328 @cbornet Here is the PR for autoinjecting objectMapper: https://github.com/swagger-api/swagger-codegen/pull/5414
@wing328 yes, the Accept header has no use for the client
I am facing the same issue, when can we expect 2.2.3 release for the above fix.
@bhuvnesharya we'll release v2.3.0 first, hopefully this month or next.
@wing328 : Thanks for the information. Does v2.3.0 support the examples display on swagger ui for spring codegen.
@bhuvnesharya yes, enhancements made to master will be sync'd to 2.3.0 branch as well.
Please give 2.3.0 a try and let us know if you've any feedback.
@wing328 : Sure , I will give a try and will let you know. Thanks :)