OpenAPITools / OpenAPITools/openapi-generator
[BUG][typescript] duplicate JSON.stringify of already stringified JSON structures
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
An OpenAPI that accepts multiple content-types is problematic for the typescript generator if one of the accepted content-types is application/json and another content-type is of schema/type: string. consider this:
paths:
/foo/bar:
/put:
requestBody:
content:
application/xml:
schema:
type: string
application/json:
schema:
$ref: '#/components/schemas/Registration'
The generated API function is this (note the string argument, despite application/json defining a schema):
public addRegistration(body?: string, _options?: Configuration): Promise<Registration> { }
now at some point the ObjectSerializer thinks it is a good thing to serialize that application/json, specifically in ObjectSerializer#stringify. because ObjectSerializer#getPreferredMediaType previously decided it's application/json. that is all technically correct, but an edge case that isn't satisfied.
because the generated API function forces me to pass addRegistration(JSON.stringify(body)); which ends up being JSON.stringify(JSON.stringify(body)); and that is not a valid JSON anymore, but a string containing a JSON.
json: { foo: "bar" }
stringified: "{ "foo": "bar" }"
stringified/stringified: ""{ \"foo\": \"bar\" }"" (whatever that is)
openapi-generator version
7.10.0 of org.openapitools:openapi-generator-maven-plugin. using the typescript generator.
OpenAPI declaration file content or url
see description above.
Generation Details
in the build section of pom.xml the following is contained.
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<configuration>
<configOptions>
<oas3>true</oas3>
<useTags>true</useTags>
</configOptions>
<generatorName>typescript</generatorName>
<output>${generator.output.dir}</output>
</configuration>
<executions>
<execution>
<id>generate-registration-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${maven.multiModuleProjectDirectory}/specs/${api.registration-controller.v2.file}</inputSpec>
<output>${generator.output.dir}/registration</output>
</configuration>
</execution>
</executions>
</plugin>
Steps to reproduce
if really required I can create a reproducer. but the bug is pretty logical imo.
I have applied the proposed fix locally, recompiled the library (without regenerating the API) and everything went just fine.
Related issues/PRs
Suggest a fix
the ObjectSerializer#stringify method should check if the provided data is already of type string before applying any "fix" to data. e.g.:
public static stringify(data: any, mediaType: string): string {
if (typeof data === 'string') {
return data;
}
if (isTextLikeMimeType(mediaType)) {
return String(data);
}
if (isJsonLikeMimeType(mediaType)) {
return JSON.stringify(data);
}
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.stringify.");
}
I am not 100% sure if this doesn't lead to other edge-cases, so opinions of maintainers are highly welcome. if maintainers approve of the proposed fix, I will submit it.
cc: @joscha
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 in modules/openapi-generator/src/main/resources/typescript/model/ObjectSerializer.mustache, especially ObjectSerializer#stringify and getPreferredMediaType. Reproduce the supplied OpenAPI case with application/json and a string schema, then verify that passing an already stringified body does not produce a doubly stringified JSON value. Done means the generated TypeScript client preserves the valid JSON request body for this case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100