Skip to content

Issue: import-mapping works (import externalRef0), but response $refs using wrong name (ExternalRef0.HTTP400) #1938

@justincranford

Description

@justincranford

Goal

I have an openapi spec split into two files yaml files, components vs paths. Reason is I want to generate separate model vs server packages.

Problem

Generated server code should be referencing strict server response components from model package as externalRef0.

  • Success response components are referenced asexternalRef0. Those compile OK.
  • Error responses components are referenced as ExternalRef0. Those don't compile.

The first character is incorrectly capitalized in server code references to externalRef0, but only the error responses.

Minimum Viable Example

I created this Git repository to demonstrate an issue in the generated server code:

It includes:

  1. README.md
  2. openapi_spec_components.yaml
  3. openapi_spec_paths.yaml
  4. openapi_gen_model.yaml
  5. openapi_gen_server.yaml
  6. internal/openapi/model/openapi_gen_model.go (generated)
  7. internal/openapi/server/openapi_gen_server.go (generated, problem)

For file 7, generated server code should be referencing all external imports from model as externalRef0. It doesn't. There is a mix of externalRef0 and ExternalRef0.

Excerpt From Generated Code

The generate commands are in the README.md. Both commands work, and server code imports model (i.e. externalRef0). However, notice something in this snippet. The HTTP200 response uses externalRef0, while the HTTP400 response uses ExternalRef0.

All of my error responses have a capitalized import name which doesn't compile.

import (
    externalRef0 "myexampleproject/internal/openapi/model"
)
type GetUserParams struct {
	Filter *externalRef0.QueryParamFilter `form:"filter,omitempty" json:"filter,omitempty"`
	Sort   *externalRef0.QueryParamSort   `form:"sort,omitempty" json:"sort,omitempty"`
	Page   *externalRef0.QueryParamPage   `form:"page,omitempty" json:"page,omitempty"`
}
type GetUserRequestObject struct {
	Params GetUserParams
}
type GetUserResponseObject interface {
	VisitGetUserResponse(ctx *fiber.Ctx) error
}

type GetUser200JSONResponse []externalRef0.User // NOT CAPITILIZED
func (response GetUser200JSONResponse) VisitGetUserResponse(ctx *fiber.Ctx) error {
	ctx.Response().Header.Set("Content-Type", "application/json")
	ctx.Status(200)
	return ctx.JSON(&response)
}

type GetUser400JSONResponse struct{ ExternalRef0.HTTP400 } // CAPITILIZED
func (response GetUser400JSONResponse) VisitGetUserResponse(ctx *fiber.Ctx) error {
	ctx.Response().Header.Set("Content-Type", "application/json")
	ctx.Status(400)
	return ctx.JSON(&response)
}

Debug

I cloned oapi-codegen and used commit cbcd935 (Mar 20, 2025) to debug. I found the issue happened when applying strict-fiber-interface.tmpl template.

return GenerateTemplates(templates, t, operations)

I tried removing ucFirst from this line in strict-fiber-interface.tmpl, and that cleared up the problem for me.

All references to externalRef0 in server code became lowercase, and the code compiled.

type GetUser400JSONResponse struct{ externalRef0.HTTP400 } // NOT CAPITILIZED
func (response GetUser400JSONResponse) VisitGetUserResponse(ctx *fiber.Ctx) error {
	ctx.Response().Header.Set("Content-Type", "application/json")
	ctx.Status(400)
	return ctx.JSON(&response)
}

Doubts

I doubt my workaround is correct. The use of ucFirst is deliberate, so removing it probably causes unwanted side effects for other use cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions