oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

1.12.2 x-go-type extension and ref don't work together

Open goshlanguage opened this issue 2 years ago • 4 comments

I'm not sure if there is a specific reason for how it works at current, but what I would like to do is externally reference say the kubernetes API spec, but also provide the go type instead of generating it.

At current I'm referencing say v1.Taint in an object, but I also want to reference it's openapi spec so that its rendered in the swagger/openapi docs:

    KubeSpec:
      type: object
      properties:
        taints:
          $ref: "https://raw.githubusercontent.com/kubernetes/kubernetes/v1.23.9/api/openapi-spec/v3/api__v1_openapi.json#/components/schemas/io.k8s.api.core.v1.Taint"
          x-go-type: v1.Taint
          x-go-type-import:
            name: v1
            path: k8s.io/api/core/v1

At current, when $ref is present, it seems to try to render the type via the import mapping, but I'd much prefer to provide the type.

Is this possible? If not, would a PR be welcome and any ideas where to start?

Thanks so much!

goshlanguage avatar Nov 17 '22 16:11 goshlanguage

It seems to be impossible to use any extension fields with a reference For example x-oapi-codegen-extra-tags together with a $ref, which would be really useful together with an ORM like bun.

Example

components:
  schemas:
    Parent:
      properties:
        id:
          type: integer
        child_id:
          type: integer
        child:
          x-oapi-codegen-extra-tags:
            bun: rel:has-one,join:child_id=id
          $ref: '#/components/schemas/Child'
    Child:
      properties:
        id:
          type: integer

Expected

// Child defines model for Child.
type Child struct {
	Id *int `json:"id,omitempty"`
}

// Parent defines model for Parent.
type Parent struct {
	Child   *Child `bun:"rel:has-one,join:child_id=id" json:"child,omitempty"`
	ChildId *int   `json:"child_id,omitempty"`
	Id      *int   `json:"id,omitempty"`
}

Actual

// Child defines model for Child.
type Child struct {
	Id *int `json:"id,omitempty"`
}

// Parent defines model for Parent.
type Parent struct {
	Child   *Child `json:"child,omitempty"`
	ChildId *int   `json:"child_id,omitempty"`
	Id      *int   `json:"id,omitempty"`
}

vennekilde avatar Aug 30 '23 14:08 vennekilde

It seems support for sibling properties with $ref got added with openapi 3.1, which updated to JSON schema 2020-12, so i assume this won't get fixed until #373 is resolved.

vennekilde avatar Aug 31 '23 10:08 vennekilde

as a workaround:

        some_property:
          allOf:
            - $ref: "#/components/schemas/some_schema"
          x-go-type: SomeGoType

tigerinus avatar Mar 13 '24 09:03 tigerinus

Apologies for the delay on getting back to you on this! Correct, this is due to $refs not being allowed siblings.

Interestingly, vacuum shows that even with an OpenAPI 3.1 spec:

# via https://github.com/deepmap/oapi-codegen/issues/863#issuecomment-1699344896
openapi: 3.1.0
components:
  schemas:
    Parent:
      properties:
        id:
          type: integer
        child_id:
          type: integer
        child:
          x-oapi-codegen-extra-tags:
            bun: rel:has-one,join:child_id=id
          $ref: '#/components/schemas/Child'
    Child:
      properties:
        id:
          type: integer

This is still deemed invalid:

spec.yaml:13:11 | error    | a `$ref` cannot be placed next to any other properties                   | no-$ref-siblings          | Schemas      | $.components.schemas.Child

jamietanna avatar Apr 20 '24 10:04 jamietanna