We have introduced support for oneOf and anyOf types in our Go SDKs.
Details
In OpenAPI, any request parameter or response payload could use union types i.e. oneOf/anyOf, which provides the flexibility of accepting different types of request parameters and returning various types of response payload. Here is an example of an API call using union types.
paths:
/send/combined:
post:
summary: Send Combined
operationId: SendCombined
requestBody:
required: true
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Car'
- $ref: '#/components/schemas/Morning'
- $ref: '#/components/schemas/Atom'
responses:
'200':
description: Send Combined successfully
content:
application/json:
schema:
anyOf:
- type: integer
format: int32
- $ref: '#/components/schemas/Atom'
- nullable: true
...
The API call, shown in the OpenApi format above, is a post-call that takes in either Car
, Morning
, or Atom
as request payload. Previously, union types were not supported therefore the endpoint was expecting the combined schema object map[string]interface{}
as a parameter. Here is how the parameter initialization would look like when calling the endpoint.
- Before
- After
sendCombinedBody := map[string]interface{}{
"NumberOfTyres": "4",
"HaveTrunk": true,
}
apiResponse, err := senderController.SendCombined(ctx, sendCombinedBody)
sendCombinedBody := models.SendCombinedBodyContainer.
FromCar(models.Car{
HaveTrunk: true,
Vehicle: models.Vehicle{
NumberOfTyres: "4",
},
})
apiResponse, err := senderController.SendCombined(ctx, sendCombinedBody)
Now, we have containers that can hold different types of data combined. With these containers, you can check what type of data is inside using the functions.
- Before
- After
apiResponse, err := senderController.SendCombined(ctx, sendCombinedBody)
if apiResponse.Data != nil {
fmt.Println(apiResponse.Data)
}
apiResponse, err := senderController.SendCombined(ctx, sendCombinedBody)
if atom, isAtom := apiResponse.Data.AsAtom(); isAtom {
fmt.Println(atom)
} else if number, isNumber := apiResponse.Data.AsNumber(); isNumber {
fmt.Println(number)
}
In the above code snippet, SendCombined
will return either an Atom
or Number
instance as the response payload. Previously, it was considered as an interface{}
object response which allowed any type of response payload. Now, with the introduction of oneOf and anyOf support, we can validate that the response can be either Atom
or Number
.
What has Changed?
The Go SDK now can handle union types in an endpoint's request and response. The type validation for union types is also added to support the oneOf/anyOf constraints.
Introducing Containers
Container types are introduced in the Go SDK to manage union types. The union types cases are contained in a container, and their marshaling and un-marshaling are also handled in the same container. This container type exposes the From<#CaseName>
method to set the case value and As<#CaseName>
methods to retrieve type converted values, respectively.
Changes in Models
Now, every model type has an internal validate()
function for all the required properties to verify that required properties are present in the model.
Changes in Endpoints
Endpoint Doc Changes
The endpoint's doc string has been updated to describe union-type parameters or return types.
- Before
- After
// SendCombined takes context, sendCombinedBody as parameters and
// returns a model.ApiResponse with interface{} data and
// an error if there was an issue with the request or response.
func (s *SenderController) SendCombined(
ctx context.Context,
sendCombinedBody interface{}) (
models.ApiResponse[interface{}],
error)
// SendCombined takes context, sendCombinedBody as parameters and
// returns a model.ApiResponse with *models.MixedParamResponse data and
// an error if there was an issue with the request or response.
func (s *SenderController) SendCombined(
ctx context.Context,
sendCombinedBody models.SendCombinedBody) (
models.ApiResponse[*models.MixedParamResponse],
error)
README Changes
Now, the Go SDK README will reflect the support for union types in parameter types or response types.
- Before
- After