ogen-go / ogen

OpenAPI v3 code generator for go
https://ogen.dev
Apache License 2.0
1.19k stars 71 forks source link

feature request: how about add method `func (s *Spec) RefParameter(n string) *NamedParameter` in `dsl.go`? #501

Open davidxifeng opened 1 year ago

davidxifeng commented 1 year ago

thanks for your great work!

there are easy to use methods like func (s *Spec) RefSchema(n string) *NamedSchema in dsl.go, but not for named parameters, how about add one for it? and maybe others fields of Components, too.

and I want a SetSecurityRequirements() for Operation, too.

if yes, I can send a pull request.

tdakkota commented 1 year ago

there are easy to use methods like func (s *Spec) RefSchema(n string) *NamedSchema in dsl.go, but not for named parameters, how about add one for it? and maybe others fields of Components, too.

and I want a SetSecurityRequirements() for Operation, too.

Yeah, I think it will be great. The DSL has not been updated for a while.

if yes, I can send a pull request.

Contributions are welcome!

davidxifeng commented 1 year ago

according to the OpenAPI spec, the type of fields like parameters of Operation Object are actually a tagged union like type:

Field Name Type
parameters [Parameter Object | Reference Object]

but currently we have

type Operation struct {

Parameters  []*Parameter     `json:"parameters,omitempty" yaml:"parameters,omitempty"`
}

type Parameter struct {
    Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"` // ref object

    // REQUIRED. The name of the parameter. Parameter names are case sensitive.
    Name string `json:"name" yaml:"name"`
    // REQUIRED. The location of the parameter. Possible values are "query", "header", "path" or "cookie".
    In string `json:"in" yaml:"in"`

so if one use a ref in operation, we will get the result spec json like this:

    {
      "$ref": "#/components/parameters/id",
      "name": "",
      "in": ""
    },

because in type Parameter name and in fields are required, and this will generate a warning in swagger editor.

I want to fix this, but that will be a lots of change, and may break some codes.

Go doesn't have native support for tagged union type, but one can use interface for a workaround. and it looks like:

type ParameterOrRef interface {
    isParameterOrRef()
}
type Ref struct {
    // REQUIRED
    Ref string `json:"$ref" yaml:"$ref"` // ref object
}
type Operation struct {
    Parameters []ParameterOrRef `json:"parameters2,omitempty" yaml:"parameters,omitempty"`
}

thanks for reading and please leave some comments and advice for this 😄

tdakkota commented 1 year ago

according to the OpenAPI spec, the type of fields like parameters of Operation Object are actually a tagged union like type:

It's much simpler to unmarshal Parameter as single structure.

Let's just set omitempty for name and in. Empty string is invalid value for the in field anyway. But it's allowed to use empty name (at least, if in is not header), probably we should use *string instead.