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

Use aliases for response type references

Open Crystalix007 opened this issue 2 years ago • 0 comments

Uses type aliases for response schema definitions.

While using a schema like:

paths:
  /example:
    get:
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OneOrAnother"

components:
  schemas:
    One:
      type: object

    Another:
      type: object

    OneOrAnother:
      oneOf:
        - $ref: "#/components/schemas/One"
        - $ref: "#/components/schemas/Another"

I noticed that this generated "strict" server code that looked like:

type OneOrAnother struct {
	union json.RawMessage
}

// ...

type GetExampleResponseObject interface {
	VisitGetExampleResponse(w http.ResponseWriter) error
}

type GetExampleResponseObject OneOrAnother

// ...

func (t OneOrAnother) MarshalJSON() ([]byte, error) {
	b, err := t.union.MarshalJSON()
	return b, err
}

func (t *OneOrAnother) UnmarshalJSON(b []byte) error {
	err := t.union.UnmarshalJSON(b)
	return err
}

However this doesn't actually work when doing the serialisation, because the type definition hides the definition of MarshalJSON(). Since the union field is private, this means the response that is actually serialised is {} every time.

Instead, we should just inherit that response from the referenced type definition. I.e. with type GetExampleResponseObject = OneOrAnother, the underlying MarshalJSON implementation will be picked up instead, and we can serialise the underlying union.

Crystalix007 avatar Mar 30 '24 10:03 Crystalix007