Background:
Currently, we use the go-swagger tool ( go-swagger/go-swagger ) which takes as input a swagger.yml file and generates both the various models from the Definitions section. We generate the client and server stubs, including the controller interface and the input types, ourselves, with the help of go-swagger's libraries. For example, related to the previous post, part of that code is here https://github.com/Clever/wag/blob/master/models/genmodels.go#L87 as part of the GenerateInputs method. Here are the rules by which models are generated: https://goswagger.io/use/models/schemas.html
We use version 0.13.0 of go-swagger (https://github.com/Clever/wag/blob/master/Gopkg.toml#L60), released Nov 2017, whereas most recent as of writing is 0.23.0 released Mar 2020. Furthermore, OpenAPI v3.0 was released on 2017-07-26 and it seems go-swagger has no intention to support it.
A few areas of interest here:
It can be confusing which fields of a model are generated as a pointer or not. The rules are here https://goswagger.io/use/models/schemas.html#nullability. The advantage of a field not being a pointer is that it's easier to work with (don't have to dereference everywhere) and null-pointer-derefence panics won't crop up at runtime. These don't effect the function of the client/server, they are just nicities. The advantage of a pointer is that you can tell the difference between a parameter being unset and being set to the 0 value, both as a means of validation (that's why required fields are pointers, so they can be validated) and as a way to provide functionality (e.g. if a field has a default, it needs to be a pointer). For comparision, The approach of e.g. the AWS API is to make everything a pointer. This makes things behave much more predictibly. Furthermore, it can cause a headache if a field is originally not listed with x-nullable, but later on you realize you need to distinguish between unset and zero value.
There are features in later versions of go-swagger, and in OpenAPI 3.0, that we might be interested in. Also we don't fully support the features of go-swagger from our version, as far as I can tell (Clever/wag
The ability to use model discriminator to do polymorphism, as well as oneOfand anyOf
OpenAPI is mostly not functional features, rather just simplifying the spec itself, but it's a nice-to-have. For example, we have want to interact with external APIs and use wag to generate ourselve a client, or provide an external source with an API.
One consideration to keep in mind is that we tend to be on both sides of client/server. For example, if a field is required, it might make sense for the server to model it with a non-pointer, since the server can do validation once at the entry-point and then assume the field has been provided everywhere else. But I think it’s more important to use the same generated model for client and server since both of those are our code.
Background: Currently, we use the go-swagger tool ( go-swagger/go-swagger ) which takes as input a swagger.yml file and generates both the various models from the Definitions section. We generate the client and server stubs, including the controller interface and the input types, ourselves, with the help of go-swagger's libraries. For example, related to the previous post, part of that code is here https://github.com/Clever/wag/blob/master/models/genmodels.go#L87 as part of the GenerateInputs method. Here are the rules by which models are generated: https://goswagger.io/use/models/schemas.html
We use version 0.13.0 of go-swagger (https://github.com/Clever/wag/blob/master/Gopkg.toml#L60), released Nov 2017, whereas most recent as of writing is 0.23.0 released Mar 2020. Furthermore, OpenAPI v3.0 was released on 2017-07-26 and it seems go-swagger has no intention to support it.
A few areas of interest here:
It can be confusing which fields of a model are generated as a pointer or not. The rules are here https://goswagger.io/use/models/schemas.html#nullability. The advantage of a field not being a pointer is that it's easier to work with (don't have to dereference everywhere) and null-pointer-derefence panics won't crop up at runtime. These don't effect the function of the client/server, they are just nicities. The advantage of a pointer is that you can tell the difference between a parameter being unset and being set to the 0 value, both as a means of validation (that's why required fields are pointers, so they can be validated) and as a way to provide functionality (e.g. if a field has a default, it needs to be a pointer). For comparision, The approach of e.g. the AWS API is to make everything a pointer. This makes things behave much more predictibly. Furthermore, it can cause a headache if a field is originally not listed with x-nullable, but later on you realize you need to distinguish between unset and zero value.
There are features in later versions of go-swagger, and in OpenAPI 3.0, that we might be interested in. Also we don't fully support the features of go-swagger from our version, as far as I can tell (Clever/wag
The ability to use model discriminator to do polymorphism, as well as oneOfand anyOf
OpenAPI is mostly not functional features, rather just simplifying the spec itself, but it's a nice-to-have. For example, we have want to interact with external APIs and use wag to generate ourselve a client, or provide an external source with an API.
One consideration to keep in mind is that we tend to be on both sides of client/server. For example, if a field is required, it might make sense for the server to model it with a non-pointer, since the server can do validation once at the entry-point and then assume the field has been provided everywhere else. But I think it’s more important to use the same generated model for client and server since both of those are our code.