swagger-api / swagger-api/swagger-codegen
[codegen] response examples not JSONified
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
This is a bug encountered whilst writing my own generator which uses examples in the responses part of the swagger.
Response examples are output using Map.toString() rather than being serialised to JSON (as happens for operation-level examples). This is because they are internally deserialised into a Map but never serialised back via ExampleGenerator or similar.
Swagger-codegen version
Bug occurs in swagger-codegen 2.2.1
Swagger declaration file
Say I have a snippet of swagger JSON as follows:
{
"swagger": "2.0",
"info": {
"version": "0.0.0",
"title": "Cloudant HTTP API"
},
"host": "localhost:5984",
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json",
"text/plain; charset=utf-8"
],
"responses": {
"202": {
"description": "Accepted – Document data accepted, but not yet stored on disk",
"headers": {
"Cache-Control": {
"type": "string"
},
"Content-Length": {
"type": "integer"
},
"Content-Type": {
"type": "string"
},
"Date": {
"type": "string"
},
"Server": {
"type": "string"
},
"Location": {
"type": "string",
"description": "Database URI location"
},
"ETag": {
"type": "string",
"description": "Quoted new document’s revision"
}
},
"schema": {
"$ref": "#/definitions/DocumentResponse"
},
"examples": {
"application/json": {
"id": "ab39fe0993049b84cfa81acd6ebad09d",
"ok": true,
"rev": "1-9c65296036141e575d32ba9c034dd3ee"
}
}
},
...
and a mustache template as follows:
{{#operations}}
{{#operation}}
{{#responses}}
{
"request": {
"method": {{httpMethod}},
"urlPattern": {{path}}
},
"response": {
"status": {{code}},
"jsonBody": {
{{#examples}}
{{{example}}}
{{/examples}}
},
"transformers": ["response-template"],
"headers": {
"Content-Type": "application/json"
}
}
}
{{/responses}}
{{/operation}}
{{/operations}}
Command line used for generation
Custom written generator, so N/A
Steps to reproduce
- Create a code generator as outlined in https://github.com/swagger-api/swagger-codegen#making-your-own-codegen-modules
- Use a mustache template as outlined above with a swagger document which has response examples
- Observe that the output has the example JSON in the incorrect format:
{
"request": {
"method": GET,
"urlPattern": /_active_tasks
},
"response": {
"status": 200,
"jsonBody": {
[{changes_done=64438, database=mailbox, pid=<0.12986.1>, progress=84, started_on=1376116576, total_changes=76215, type=database_compaction, updated_on=1376116619}, {changes_done=14443, database=mailbox, design_document=c9753817b3ba7c674d92361f24f59b9f, pid=<0.10461.3>, progress=18, started_on=1376116621, total_changes=76215, type=indexer, updated_on=1376116650}]
},
"transformers": ["response-template"],
"headers": {
"Content-Type": "application/json"
}
}
}
- Actual output should resemble JSON in the
jsonBodysection (note this isn't perfect but it's much closer to the desired output):
{
"request": {
"method": GET,
"urlPattern": /_active_tasks
},
"response": {
"status": 200,
"jsonBody": {
"application/json"
[ {
"changes_done" : 64438,
"database" : "mailbox",
"pid" : "<0.12986.1>",
"progress" : 84,
"started_on" : 1376116576,
"total_changes" : 76215,
"type" : "database_compaction",
"updated_on" : 1376116619
}, {
"changes_done" : 14443,
"database" : "mailbox",
"design_document" : "c9753817b3ba7c674d92361f24f59b9f",
"pid" : "<0.10461.3>",
"progress" : 18,
"started_on" : 1376116621,
"total_changes" : 76215,
"type" : "indexer",
"updated_on" : 1376116650
} ]
},
"transformers": ["response-template"],
"headers": {
"Content-Type": "application/json"
}
}
}
Related issues
Couldn't find anything relevant.
Suggested fix
Over-riding postProcessOperations in my generator and cribbing some code from ExampleGenerator got me the "nearly correct" output above:
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
// Json prettify the output examples
@SuppressWarnings("unchecked")
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) {
List<CodegenResponse> responses = operation.responses;
for (CodegenResponse response : responses) {
List<Map<String, Object>> examples = response.examples;
List<Map<String, Object>> output = new ArrayList<Map<String, Object>>();
if (examples != null) {
for (Map<String, Object> example : examples) {
for (Map.Entry<String, Object> entry : example.entrySet()) {
final Map<String, Object> kv = new HashMap<String, Object>();
kv.put("contentType", entry.getKey());
kv.put("example", Json.pretty(entry.getValue()));
output.add(kv);
}
response.examples = output;
}
}
}
}
return objs;
}
I can contribute a PR if desired but I need to seek permission from my employer first.
Additionally, ExampleGenerator should probably make a better effort at serialisation. For instance if the sample is in XML then it should serialised back to XML, not JSON.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ExampleGenerator and the response.examples handling shown in postProcessOperations, then compare how operation-level examples are serialized. Update response example processing so JSON examples are emitted as JSON instead of Map.toString() output, and verify the generated custom-template output against the reproduction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100