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

openapi3gen: add CreateComponentSchemas option to export object schemas to components #914

Closed
wants to merge 30 commits into from

Conversation

EnriqueL8
Copy link
Contributor

@EnriqueL8 EnriqueL8 commented Feb 22, 2024

PR to start the discussion on #909

@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8 let me try to test it and thus help you.

@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8 Thanks!

@EnriqueL8
Copy link
Contributor Author

EnriqueL8 commented Feb 22, 2024

There is a problem in some cases where it actually makes it worse - I think introducing an annotation to ignore structs to be schemas would be helpful as well. Maybe using the struct tag?

So in the case where an api returns an object such as:

{
   size: 50
   objects: [
       <array-with-objects>
   ]
}

The top level should be a schema on the path itself but the type for the object should be in #/components/schema

@fenollp
Copy link
Collaborator

fenollp commented Feb 22, 2024

Hi! Please run ./docs.sh and push the diff so CI can continue.

@fenollp fenollp changed the title Add ability to export object schemas to components openapi3gen: add CreateComponentSchemas option to export object schemas to components Feb 22, 2024
@EnriqueL8
Copy link
Contributor Author

Thanks - just making a few more change and will run it

Signed-off-by: Enrique Lacal <[email protected]>
Signed-off-by: Enrique Lacal <[email protected]>
@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8,

I'm trying to compile my project having replaced original kin-openapi with your branch.

Observe the problem:

../../../go/pkg/mod/github.com/davidebianchi/[email protected]/main.go:115:19: cannot use openapi3.Paths{} (value of type openapi3.Paths) as *openapi3.Paths value in assignment
../../../go/pkg/mod/github.com/davidebianchi/[email protected]/operation.go:31:22: invalid argument: cannot make openapi3.Responses; type must be slice, map, or channel
../../../go/pkg/mod/github.com/davidebianchi/[email protected]/route.go:101:29: invalid argument: cannot make openapi3.Responses; type must be slice, map, or channel

I guess it because the [email protected] refers to the incompatible version of kin-openapi

Exactly the same problem as mentioned here https://github.com/davidebianchi/gswagger/actions/runs/7914093080/job/21603115911

@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8 there is one problem. If there are different types in different packages have the same name then the "NewSchemaRefForValue" produces one component, the same ref.

Example:

package root:

 // Imported package with conflicting type name
import "github.com/getkin/kin-openapi/openapi3gen/subpkg"

type AnotherStruct struct {
  Field1 string `json:"field1"`
  Field2 string `json:"field2"`
  Field3 string `json:"field3"`
}
type RecursiveType struct {
  Field1        string        `json:"field1"`
  Field2        string        `json:"field2"`
  Field3        string        `json:"field3"`
  AnotherStruct AnotherStruct `json:"children,omitempty"`
  
  // Use imported type
  AnotherStruct2         subpkg.AnotherStruct    `json:"children,omitempty"`
}
package subpkg:

type AnotherStruct struct {
  Field4 string `json:"field1"`
}

@EnriqueL8
Copy link
Contributor Author

Aah I see - is that something that we should document as a limitation as it seems quite improbable? The same thing would occur if that type is cyclic

@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8, I think it makes to supply an optional type name generator and use it at openapi3gen.go:315 ... diving into the code

@sskserk
Copy link
Contributor

sskserk commented Feb 22, 2024

@EnriqueL8 please take a look at your forked repository. I have created a MR into your developed branch. I propose a new option making it possible to customize the generated type name

@EnriqueL8
Copy link
Contributor Author

thanks @sskserk I'll take a look

@EnriqueL8
Copy link
Contributor Author

Added your commit

@sskserk
Copy link
Contributor

sskserk commented Feb 23, 2024

@EnriqueL8 let me create a couple of additional tests. I'll bring an additional MR into the current branch.

@EnriqueL8
Copy link
Contributor Author

@sskserk awesome - I'm also testing this

Signed-off-by: Enrique Lacal <[email protected]>
Signed-off-by: Enrique Lacal <[email protected]>
@EnriqueL8 EnriqueL8 marked this pull request as ready for review February 23, 2024 14:54
@EnriqueL8
Copy link
Contributor Author

I'm wondering if we should have a customiser for ignoring components instead of only top level? will leave to the reviewer to decide @fenollp fyi

@EnriqueL8
Copy link
Contributor Author

EnriqueL8 commented Feb 23, 2024

@sskserk I've found another issue here when you have a generic field, ignoring the top level is not enough if it's nested so you want to be able to not add generics to component schemas as you will get one per type use which is awful

@EnriqueL8
Copy link
Contributor Author

Pushed up a commit for handling generics - I'm sure there is a better way so any thoughts appreciated

Signed-off-by: Enrique Lacal <[email protected]>
@sskserk
Copy link
Contributor

sskserk commented Feb 28, 2024

@EnriqueL8 & @fenollp , let me just share the news. A related project has been fixed as well davidebianchi/gswagger#148

@EnriqueL8
Copy link
Contributor Author

This is ready for review

Signed-off-by: Enrique Lacal <[email protected]>
Signed-off-by: Enrique Lacal <[email protected]>
@EnriqueL8
Copy link
Contributor Author

EnriqueL8 commented Feb 29, 2024

@fenollp I'm seeing a lot of issues with found unresolved ref , it seem that the package so far made an assumption that all refs are resolved? So no reference should exist in the final document?

It might be that I am using validate wrong and should be loading the document generated into a loader and the validate it? Okay that works if I do:

  • SwaggerGen.Generate a document
  • Load that into a loader (this will resolve the references)
  • Validate that document I loaded

Maybe there is a flag on the validate to allow references? or is that not a valid OpenAPI3 document?

@EnriqueL8
Copy link
Contributor Author

I've noticed another issue with map[string]interface{} as we are using the type object to export the schema. Ideally we shouldn't be exporting the top level maps to schemas.

@fenollp if you get a chance would appreciate a first review as well 😃

@EnriqueL8
Copy link
Contributor Author

Alright pushed up fix for maps, only perform the export for structs

@sskserk
Copy link
Contributor

sskserk commented Mar 11, 2024

@fenollp do you think this MR is ready to be merged?

@EnriqueL8
Copy link
Contributor Author

@fenollp any bandwidth to take a look at this? Note would appreciate your input on #914 (comment)

Copy link
Collaborator

@fenollp fenollp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nitpicks, LGTM!

openapi3gen/subpkg/sub_type.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen_test.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen_test.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen_test.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen.go Outdated Show resolved Hide resolved

// Best way I could find to check that
// this current type is a generic
isGeneric, err := regexp.Match(`^.*\[.*\]$`, []byte(t.Name()))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just checking that the last rune is ]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be an array in that case?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, then runes[-1] == ']' && runes[-2] != '['

openapi3gen/openapi3gen.go Outdated Show resolved Hide resolved
openapi3gen/openapi3gen_test.go Outdated Show resolved Hide resolved
@EnriqueL8
Copy link
Contributor Author

@fenollp thanks for the review! Will push changes up soon

sskserk and others added 5 commits March 25, 2024 22:09
@EnriqueL8
Copy link
Contributor Author

@fenollp Ready for re-review 😃

Copy link
Collaborator

@fenollp fenollp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's all down to that regex thing and we're good :)


// Best way I could find to check that
// this current type is a generic
isGeneric, err := regexp.Match(`^.*\[.*\]$`, []byte(t.Name()))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, then runes[-1] == ']' && runes[-2] != '['

@fenollp
Copy link
Collaborator

fenollp commented Apr 6, 2024

Hey there! Please rebase & I'll make this move along.

Copy link
Collaborator

@fenollp fenollp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase please

@EnriqueL8
Copy link
Contributor Author

@fenollp Thanks, sorry was away and not available to rebase! It's a shame that the commit was squashed and not awarded to the contributors of the PR

@fenollp
Copy link
Collaborator

fenollp commented Apr 9, 2024

Hi @EnriqueL8, you're right. I messed up while rebasing your PR and the shared attribution went to someone that's not even taken part in that part of the lib. I should have checked, sorry.

I do not mean to steal anyone's work and would very much prefer to give attribution where it's deserved (e.g. here). So I suggest this: send a PR that both reverts then applies your commit (add some changes if you want but that's not needed). At least this way attribution is assured. If you have other ideas, I'm open :)

@EnriqueL8
Copy link
Contributor Author

Sounds good - I'll do that!

@EnriqueL8
Copy link
Contributor Author

@fenollp I think this solves it #937

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.

#/components/schemas across routes
3 participants