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

ability to overwrite how a type is going to be generated in the spec #222

Open
phenpessoa opened this issue Nov 10, 2024 · 17 comments
Open
Labels
feature-request New feature or request

Comments

@phenpessoa
Copy link

Is your feature request related to a problem? Please describe.
Yes, currently there is no way to change how a type is going to be described in the OpenAPI spec, even though we might be using custom Marshalers/Unmarshalers.

Describe the solution you'd like
I'd like to have an option to manually overwrite how a type will be described in the OpenAPI spec. I was thinking that maybe it could be an interface that the type implements and returns some sort of data of how it should be described. But open to suggestions.

Describe alternatives you've considered
Currently the only alternative is editing the spec file manually.

Additional context
To give a concrete example, I have this type:

type Foo struct {
    Bar Option[string] `json:"bar"`
}

type Option[T any] struct {
    Valid bool
    Val   T
}

And in the spec it will show up as

Foo:
  description: Foo schema
  properties:
    bar:
      properties:
        Val:
          type: string
        Valid:
          type: boolean
      type: object
  type: object

But, the option field there basically is just a way to make the field nullable, so I'd like it to be encoded as:

Foo:
  description: Foo schema
  properties:
    bar:
      type: [string, 'null']
  type: object
@phenpessoa phenpessoa added the feature-request New feature or request label Nov 10, 2024
@dylanhitt
Copy link
Collaborator

This is a great idea!

We also appreciate your thoughtfulness when describing the feature. Im fairly certain you can just overwrite a route completely if needed, but I’m away from a computer at least til end of the week.

That being said, providing an idiomatic way to just overwrite an entires route spec is a great idea.

@dylanhitt
Copy link
Collaborator

dylanhitt commented Nov 14, 2024

I guess the question is do we want the input for this override to be a Go type or do we want to allow the user to construct the type (to be exact openapi3.Schema) themselves? Or maybe both?

@phenpessoa

To walk through your idea some so I understand. You're describing that in the case above Foo would implement say a function called FuegoAPIOverride() and the fuego route registration would call that somewhere?

@phenpessoa
Copy link
Author

To walk through your idea some so I understand. You're describing that in the case above Foo would implement say a function called FuegoAPIOverride() and the fuego route registration would call that somewhere?

Yup! That was my original idea. And that method would return an object (maybe an object and an error?) which is an OpenAPI Schema/Object/Model. (Not sure if I'm using the right terminology here, sorry).

So it would be something like this:

// This type would be specified by Fuego, not by the user.
type OpenAPISchema struct {
	Type       []string            `yaml:"type"       json:"type"`
	Required   []string            `yaml:"required"   json:"required"`
	Properties map[string]Property `yaml:"properties" json:"properties"`
	// ... any other fields
}

type Property struct {
	Type    []string `yaml:"type"    json:"type"`
	Minimum int      `yaml:"minimum" json:"minimum"`
	Maximum int      `yaml:"maximum" json:"maximum"`
	// ... any other fields
}


// And then we could have an interface that types could implement
// This name is not a suggestion, just an example
type OpenAPISchemer interface {
    FuegoAPIOverride() OpenAPISchema
}

And then users would implement this interface for any types they see fit.

@dylanhitt
Copy link
Collaborator

dylanhitt commented Nov 20, 2024

Just a thought for now. I think we'd want to continue our options pattern. Maybe a OptionCustomSchema(whatever the schema input is) In this case we'd want the caller to construct the entire schema. They could call our helpers if need be

@phenpessoa
Copy link
Author

Just a thought for now. I think we'd want to continue our options pattern. Maybe a OptionCustomSchema(whatever the schema input is) In this case we'd want the caller to construct the entire schema. They could call our helpers if need be

I’d prefer a more granular, per type approach.
One of the selling points of fuego for me is the ability to automatically generate an OpenAPI schema from types. That would defeat that (unless I’m misunderstanding) and require the user build the entire OpenAPI schema themselves.

@dylanhitt
Copy link
Collaborator

dylanhitt commented Nov 20, 2024

🤔

OH. I see now. I didn’t really look at your example close enough. I still think the option pattern can be used how you described, but I’ll look at each implementation style sometime this week.

Thank you for walking me through that. I appreciate it

@EwenQuim
Copy link
Member

EwenQuim commented Dec 10, 2024

I'll take it this week. Good issue. I'm not sure options pattern can solve that, even if you can override 200 response, it's a bit more broad than what's asked in this issue.

Also, sorry for the delay. I worked a lot for new features in Fuego but I missed yours, really sorry about that!

@phenpessoa
Copy link
Author

@EwenQuim nothing to be sorry for. Thanks for looking into it!

@DimShadoWWW
Copy link

Would it be possible to provide a way to specify a custom version of parseStructTags?

This could allow support for customized struct in field's tag that might enhance the OpenAPI output.

For example:

Status string `json:"status" openapi:"oneof=active:Currently active;inactive:No longer active;pending:Pending activation"`

@EwenQuim
Copy link
Member

Mmmh good idea!

@DimShadoWWW
Copy link

For example, I need support for enums and, if possible, descriptions for their values.

@EwenQuim
Copy link
Member

To add support for enums in Fuego, we need an idea of how to make enums in Go ! 😢

@EwenQuim
Copy link
Member

For the moment I'm busy making the Gin compatibility, if anyone is interested taking the issue it would be nice, otherwise expect it late January

@eiswind
Copy link

eiswind commented Jan 1, 2025

At my side I'd like to make some things readonly in the openapi document. So I like the idea from
#222 (comment)

@EwenQuim
Copy link
Member

EwenQuim commented Jan 1, 2025

Good idea. I think we can work on:

  • let the users freely extend the parsing of struct tags into OpenAPI doc
  • integrate these ideas continuously into Fuego if they are generic enough (enums, readonly...) (and provide runtime checks+validation additionnaly?)

It's a philosophy we already promote in Fuego but not in this part of the code right now :) Please don't hesitate to tackle this issue if you have time, otherwise I'll do it later

@DimShadoWWW
Copy link

I'm working on this as part of PR #328, following this comment.

@DimShadoWWW
Copy link

Pushed in commit 357b6b9

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

No branches or pull requests

5 participants