Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the structure of generated models and generated input types #310

Open
aastein opened this issue Dec 4, 2020 · 0 comments
Open

Change the structure of generated models and generated input types #310

aastein opened this issue Dec 4, 2020 · 0 comments

Comments

@aastein
Copy link
Contributor

aastein commented Dec 4, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant