SyncMessages omits some query params; completely breaks incremental sync (ISync)
gplusplus314 opened this issue · 4 comments
The SyncMessages
func does not correctly handle the following query params:
direction
messageType
syncType
I discovered this issue while trying to perform an incremental sync. The API responded with an error that said my syncToken
was invalid. After stepping through with a debugger and tracing around, I landed on the broken generated code.
The issue is that all three of these query params, although singular, are only being included when they pass a type assertion for a slice. For example, this:
if localVarTempParam, localVarOk := localVarOptionals["direction"].([]string); localVarOk
Should be changed to this:
if localVarTempParam, localVarOk := localVarOptionals["direction"].(string); localVarOk
While it's an inconvenience for two of the parameters, it completely breaks incremental sync functionality.
Thanks!
Upon further investigation, this seems to be a class of errors related to the code generation of enum types (Swagger spec collectionFormat: "multi"
). In the swagger spec, whenever we have an enum that gets mapped to a map[string]interface{}
, a type assertion for []string
is made, when it should be string
.
I'm not familiar with the code generation, but if you point me in the right direction, I'd be willing to contribute a more permanent fix.
Generally I do a few things to fix the auto-generated code:
- Bugs in the Swagger spec (swagger_spec.yaml) are fixed in the spec so the code can be auto-generated again.
- Bugs in Swagger Codegen are (a) fixed in swagger_codegen_command.sh post processing and then (b) reported to the https://github.com/swagger-api/swagger-codegen project such as: swagger-api/swagger-codegen#8039
By providing the changes in the Swagger spec and post-generation commands, the changes will persist after rebuilds with an updated spec.
While it's an inconvenience for two of the parameters, it completely breaks incremental sync functionality.
I agree this isn't necessary when there are only two enumerated values, since both values is equivalent to specifying no values. For these, one approach would be to remove collectionType
.
While most occurrences only have 2 values, listExtensionPhoneNumbers
/ extension/phone-number
has more:
collectionFormat: "multi"
enum:
- "MainCompanyNumber"
- "AdditionalCompanyNumber"
- "CompanyNumber"
- "DirectNumber"
- "CompanyFaxNumber"
- "ForwardedNumber"
I just finished upgrading the SDK to use OpenAPI Generator. It's a fork of Swagger Codegen with a benefit of more frequent releases so we can see about getting support for this in. I'll spend some time looking into this and may be able to provide some info on how to proceed.
You can learn more about the project here:
For this investigation, I'll use listExtensionPhoneNumbers
as the example.
Here's the spec:
-
name: "usageType"
in: "query"
description: "Usage type of the phone number"
required: false
type: "array"
items:
type: "string"
collectionFormat: "multi"
enum:
- "MainCompanyNumber"
- "AdditionalCompanyNumber"
- "CompanyNumber"
- "DirectNumber"
- "CompanyFaxNumber"
- "ForwardedNumber"
Here's the generated code:
type ListExtensionPhoneNumbersOpts struct {
UsageType optional.Interface
Page optional.Int32
PerPage optional.Int32
}
if localVarOptionals != nil && localVarOptionals.UsageType.IsSet() {
localVarQueryParams.Add("usageType", parameterToString(localVarOptionals.UsageType.Value(), "multi"))
}
It seems like the desired code would be:
type ListExtensionPhoneNumbersOpts struct {
UsageType optional.SliceString
Page optional.Int32
PerPage optional.Int32
}
if localVarOptionals != nil && localVarOptionals.UsageType.IsSet() {
for _, s := range localVarOptionals.UsageType.Value() {
localVarQueryParams.Add("usageType", parameterToString(localVarOptionals.UsageType.Value(), "multi"))
}
}
optional
is a library by antihax that handles Go's non-null zero values: https://github.com/antihax/optional
Different collection formats are here:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md