Failed to generate enum types defined in responses and allOf
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
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.
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 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.
@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: "-"
Still having this issue, might look into it when I get time