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

Failed to generate enum types defined in responses and allOf

Open joesonw opened this issue 1 year ago • 5 comments

source: https://clerk.com/docs/reference/backend-api

config

generate:
  models: true
  client: true

it failed to generate types for schemas defined in response and allOf peroperties

joesonw avatar Sep 13 '24 22:09 joesonw

Can confirm this happens to me as well. I have made the following openapi schemas:

get:
  summary: Test
  responses:
    '200':
      description: "Listing"
      content:
        application/json:
          schema:
            type: object
            properties:
              test:
                type: string
                enum: ["A", "B"]


post:
  summary: Test
  requestBody:
    content:
      application/json:
        schema:
          type: object
          properties:
            test: 
              type: string
              enum: ["ABC", "123"]
  responses:
    '200':
      description: ""

The enum for the return value (for the get endpoint) does not get generated:

type GetListingsId200JSONResponse struct {
	Test *GetListingsId200JSONResponseTest `json:"test,omitempty"` // 1. compiler: undefined: GetListingsId200JSONResponseTest [UndeclaredName]
}

But the post endpoint works fine

EDIT:

A workaround for this is to define the enums in the components.schemas part of the root API definition. You then have to refer to it like this:

get:
  summary: Test
  responses:
    '200':
      description: "Listing"
      content:
        application/json:
          schema:
            type: object
            properties:
              test:
                $ref: '#/components/schemas/TestEnum'

EDIT 2:

The example above works in that case, but it seems to break some other stuff somewhere else unfortunately. I don't think the trick works if you have too many nested refs to resolve.

Napam avatar Oct 21 '24 16:10 Napam

After some more digging I found a way that worked both with allOf and in responses, and for post bodies and whatnot. As stated in the README.md@fd1f9b3#import-mapping, we can specify

# the oapi-codegen config file
# ... other stuff here
output-options:
    skip-prune: true

And then I had to specify the actual file path in the $ref values as well and not #/components/schemas/..., that is for instance (interestingly enough, the #/components/schemas worked sometimes for generating, but I don't actually think it is valid openapi, at least swagger ui could not understand it)


get:
  summary: Test
  responses:
    '200':
      description: "Testies"
      content:
        application/json:
          schema:
            type: object
            properties:
              test:
                $ref: '../common.yaml#/components/schemas/TestEnum' # Like this
            # add this.  ^^^^^^^^^^^^

After adding the file path, I would get the error

error generating code: error creating operation definitions: error generating body definitions: error generating request body definition: error generating Go schema for property 'test': error turning reference (../common.yaml#/components/schemas/TestEnum) into a Go type: unrecognized external reference '../common.yaml'; please provide the known import for this reference using option --import-mapping

I could fix that error by adjusting the config:

# the oapi-codegen config file
# ... other stuff here
output-options:
    skip-prune: true
import-mapping:
    ../common.yaml: "-"

TLDR for my case:

Assume you have a common file to be imported at ../common.yaml (relative to the file that is going to import common). Then ensure that you add the file path to the ref, e.g. $ref: '../common.yaml#/components/schemas/CommonType', have this in the config:

# the oapi-codegen config file
# ... other stuff here
output-options:
    skip-prune: true
import-mapping:
    ../common.yaml: "-"

Napam avatar Oct 23 '24 18:10 Napam

@Napam I tried to follow along with your workaround and I ended up with this in the output:

	externalRef0 "-"

Which of course does not resolve.

In your example, is "-" perhaps a reference to a hand-written version of the enum in question? In my case, the enum was originally defined inline and I expected not to need to hand-write it.


Regardless of workarounds, I believe this issue deserves a higher prioritization. If the CLI fails to support all features of the schema, that’s one thing. When it produces output that doesn’t compile, that’s quite another.

MattiasMartens avatar Nov 13 '24 21:11 MattiasMartens

@Napam I tried to follow along with your workaround and I ended up with this in the output:

	externalRef0 "-"

Which of course does not resolve.

In your example, is "-" perhaps a reference to a hand-written version of the enum in question? In my case, the enum was originally defined inline and I expected not to need to hand-write it.

@MattiasMartens

The "-" is according to the docs:

Since oapi-codegen v2.4.0, it is now possible to split large OpenAPI specifications into the same Go package, using the "self" mapping (denoted by a -) when using Import Mapping.

So it was basically just to make refs such as this ../common.yaml#/components/schemas/TestEnum work. But I just checked what I did, and my setup is a little bit different now (don't remember exactly why I changed it), but basically;

I have my root openapi file, and within that I have defined some "shared types":

components:
  schemas:
    ...

Then I refer to them using

$ref: ../the_root_spec.yaml#/components/schemas/ASharedType

And my openapi config is:

package: api
generate:
  echo-server: true
  models: true
  client: false
  strict-server: true
output: ./internal/generated/openapi.go
output-options:
  skip-prune: true
import-mapping:
  ../the_root_spec_yaml: "-"

Napam avatar Nov 14 '24 06:11 Napam

Still having this issue, might look into it when I get time

AidanWelch avatar May 25 '25 19:05 AidanWelch