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

Use form tags when available #1422

Merged
merged 3 commits into from
Mar 13, 2023
Merged

Use form tags when available #1422

merged 3 commits into from
Mar 13, 2023

Conversation

pconstantinou
Copy link
Contributor

Describe the PR
swaggo doesn't look at the form tag on structs to determine field names, only the json tag. This update sets the field name in the swagger files to the form tag if it exists. This will match what gin binds to.

Relation issue
This issue was also raised here:
#1411

Additional context
Add any other context about the problem here.

@ubogdan
Copy link
Contributor

ubogdan commented Dec 14, 2022

Why do we want to introduce such a fallback?

@sdghchj What do you think about this change?

@pconstantinou
Copy link
Contributor Author

pconstantinou commented Dec 14, 2022

The swagger file that's currently generated is incorrect. For example, I have a struct of the form:

type form struct {
	// UserID userID for whom the query is being performed
	UserID string `form:"user_id" binding:"required,uuid"`
}

which represents the GET input parameters for my handler.
Before this fix, the generated YAML output says the parameter name is userID. The introspection looks for JSON tags on the struct but doesn't check for the presence of the form tag so it falls back to the field name.

By including the change, developers who explicitly set the json tag won't see any change in output, but those who provided only a form tag will get a result that will make the swagger file compatible with gin.

More generally, the form tag is not currently supported. This change will add support for it.

Here's an example from the gin documentation of how the form tag is used:
https://gin-gonic.com/docs/examples/bind-query-or-post/

@sdghchj
Copy link
Member

sdghchj commented Dec 15, 2022

What if a struct is shared by two routers, one use it as form request model, the other use it as response model?

@sdghchj
Copy link
Member

sdghchj commented Dec 15, 2022

Is there a better way to support this? Such as parsing form tag into extensions with a special extension name and pick it when parsing request according to @accept, finally remove all the form extensions from all exported struct fields schemas.

@pconstantinou
Copy link
Contributor Author

pconstantinou commented Dec 15, 2022

Yes. An optimal solution might be to select the json vs. form tag based on the @accept tag to allow for the reuse of structs both as query parameters as well as JSON responses where you want (for reasons I can't imagine) to have inconsistent names. However, even in those cases, the likely scenario is that the json and form tags will match. In general, a tag is only provided when the default field name is not desired.

The only need for that enhancement is specificity when the tags are not consistent.

The current behavior on master is wrong for query parameters. It fails to generate correct parameter names for GET and POST parameter requests when form tags are used.

My change is an improvement in that JSON still takes priority when no other tag is used OR when the json tag is used. The form tag will work if no other is tag specified. So it reduces the number of bugs without adding any new ones.

Without this change, how is one supposed to define an OPENAPI definition for query parameters using a struct?

I am not clear why one would put a form tag on a field without the intent to use it.

@pconstantinou
Copy link
Contributor Author

This pull request is using the same approach for query tags.
#1251
@Ferrany1

@ubogdan
Copy link
Contributor

ubogdan commented Dec 15, 2022

@pconstantinou As @sdghchj suggested, the struct can be shared between "accept" and "query", but after it gets parsed which models should we store into documentation the one handling JSON tags, the one with form tags, or the one with query tags?

@rafamarqqqs
Copy link

rafamarqqqs commented Jan 17, 2023

Any updates on this? I'm also having some trouble using the uppercase acronym pattern naming in Go and requesting the camelcase style in the API with the form tag (e.g: TaxID struct field name with the tag form:"taxId" becomes taxID, even with the default camelcase strategy).

@sdghchj
Copy link
Member

sdghchj commented Mar 13, 2023

Anyway, this is a temporary solution.

@sdghchj sdghchj merged commit 19ddb4d into swaggo:master Mar 13, 2023
@sdghchj sdghchj mentioned this pull request Mar 13, 2023
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

Successfully merging this pull request may close these issues.

4 participants