Motivation
I want to be able de generate client and server from an OpenAPI specification, for an API which use XML as content type for request and response body.
Currently, application/xml contents for request and response are not generated by swift-openapi-generator, and only OpenAPIRuntime.HTTPBody enum associated value is available for xml content.
A Workaround is to use an external XML encoder and decoder, like CoreOffice XMLCoder, and make the encoding from / decoding to HTTPBody.
struct Credentials: Encodable {
var username: String
var password_hash: String
}
struct Token: Decodable {
var token: String
}
let credentials = Credentials(username: "johnapplessed", password_hash: "d2hhdCBkaWQgeW91IGV4cGVjdD8=")
let encoder = XMLEncoder()
let encoded = try encoder.encode(credentials)
let response = try await client.authenticate(body: .xml(HTTPBody(encoded)))
let xmlBody = try response.ok.body.xml
let xmlData = try await Data(collecting: xmlBody, upTo: .max)
let decoder = XMLDecoder()
let decoded = try decoder.decode(Token.self, from: xmlData)
let token = decoded.token
Proposed solution
One quick solution could be to implement a new CodingStrategy for xml in swift-openapi-generator.
For swift-openapi-runtime, we could add the following methods to Converter:
| Client/server |
Set/get |
Schema location |
Coding strategy |
Optional/required |
Method name |
| client |
set |
request body |
XML |
optional |
setOptionalRequestBodyAsXML |
| client |
set |
request body |
XML |
required |
setRequiredRequestBodyAsXML |
| client |
get |
response body |
XML |
required |
getResponseBodyAsXML |
| server |
get |
request body |
XML |
optional |
getOptionalRequestBodyAsXML |
| server |
get |
request body |
XML |
required |
getRequiredRequestBodyAsXML |
| server |
set |
response body |
XML |
required |
setResponseBodyAsXML |
Encoding / Decoding logic can be implemented into these methods, with an XML encoder / decoder.
As Converter have encoder and decoder properties as type JSONEncoder and JSONDecoder, we could:
- Rename
encoder to jsonEncoder and decoder to jsonDecoder, and instantiate a xmlEncoder and xmlDecoder in Converter init.
- Instantiate a
XMLEncoder or XMLDecoder in call of methods above.
Example:
extension Converter {
public func setRequiredRequestBodyAsXML<T: Encodable>(
_ value: T,
headerFields: inout HTTPFields,
contentType: String
) throws -> HTTPBody {
try setRequiredRequestBody(
value,
headerFields: &headerFields,
contentType: contentType,
convert: convertBodyCodableToXML
)
}
}
Alternatives considered
I found that Converter struct is not suited for adding support of new content type. With the proposed solution, the Converter struct will have types of <#HTTPMediaType#>Encoder and <#HTTPMediaType#>Decoder, while not necessarily needed.
For XML only API, Converter still need a JSONEncoder and JSONDecoder.
I thought that, maybe, and I would like to have your opinion on this, we must implement a Converter for a specific http media type, like Vapor is doing with ContentEncoder and ContentDecoder. Each http media type would be assigned to a specific Converter.
What's your thoughts about this?
Additional information
No response
Motivation
I want to be able de generate client and server from an OpenAPI specification, for an API which use XML as content type for request and response body.
Currently,
application/xmlcontents for request and response are not generated byswift-openapi-generator, and onlyOpenAPIRuntime.HTTPBodyenum associated value is available for xml content.A Workaround is to use an external XML encoder and decoder, like CoreOffice XMLCoder, and make the encoding from / decoding to
HTTPBody.Proposed solution
One quick solution could be to implement a new
CodingStrategyfor xml inswift-openapi-generator.For
swift-openapi-runtime, we could add the following methods toConverter:Encoding / Decoding logic can be implemented into these methods, with an XML encoder / decoder.
As
Converterhaveencoderanddecoderproperties as typeJSONEncoderandJSONDecoder, we could:encodertojsonEncoderanddecodertojsonDecoder, and instantiate axmlEncoderandxmlDecoderinConverterinit.XMLEncoderorXMLDecoderin call of methods above.Example:
Alternatives considered
I found that
Converterstruct is not suited for adding support of new content type. With the proposed solution, theConverterstruct will have types of<#HTTPMediaType#>Encoderand<#HTTPMediaType#>Decoder, while not necessarily needed.For XML only API,
Converterstill need aJSONEncoderandJSONDecoder.I thought that, maybe, and I would like to have your opinion on this, we must implement a
Converterfor a specific http media type, like Vapor is doing withContentEncoderandContentDecoder. Each http media type would be assigned to a specific Converter.What's your thoughts about this?
Additional information
No response