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)? Yes
- What's the version of OpenAPI Generator used?
master
- Have you search for related issues/PRs?
- What's the actual output vs expected output?
Description
I have an API returning JSON (always, the Content-Type on the answer is JSON, the documentation specified JSON, etc.
openapi-generator version
master
OpenAPI declaration file content or url
openapi: 3.0.1
info:
title: Test string API
version: 1.0.0
components:
responses:
OK_200:
description: OK
content:
application/json:
schema:
type: "string"
paths:
/ping:
get:
summary: Endpoint
description: Returns a JSON-encoded string
responses:
'200':
$ref: "#/components/responses/OK_200"
Command line used for generation
generate -i string-api.yaml -g swift4 -o output
Steps to reproduce
- Implement the API and return the following full HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
"API String Response"
- Query the API using the code generated
- The result of the API is
"\"API String Response\""
instead of"API String Response"
The JSON is not deserialized. Despite the appropriate Content-Type
and documentation.
Related issues/PRs
None I could find.
Suggest a fix
The issue seems to arise from this special case:
https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/swift4/AlamofireImplementations.mustache#L362-L380
Although I do understand the use case (sometimes, we just want the response's body as string, not interpreted), this is preventing proper use of the code when we have an API returning a simple string.
Obviously changing the API to wrap the value inside an object or an array isn't acceptable (nor always possible if the API isn't under our control).
I would suggest to use the AlamofireRequestBuilder
(returned by getNonDecodableBuilder
) for this use case. While the AlamofireDecodableRequestBuilder
should always try to decode its content.
Moreover, because of https://bugs.swift.org/browse/SR-6163, We won't be able to rely on JSONDecoder for String values (same is true for plain numbers (int/float), boolean and null). In all these cases, we should add a case in the AlamofireDecodableRequestBuilder
to use JSONSerialization.jsonObject(with: json, options: .allowFragments)) as? T
instead. The existing special case for String
should be removed and replaced by this as well.
Note: There might be many issues linked to https://forums.swift.org/t/top-level-t-self-encoded-as-number-json-fragment/11001 as well.
Maybe switching to JSONSerialization
with .allowFragments
as the JSON Serializer/Deserializer would be a good idea...