huma icon indicating copy to clipboard operation
huma copied to clipboard

[question/feature]: Is configuring multiple media types on request/response for the same operation possible?

Open superstas opened this issue 5 months ago • 0 comments

Hi there!

I have a question/feature request.

I want to achieve the state where a single operation has multiple media types on request and response, and the exact type that's going to be used ( for unmarshalling the request/marshalling the response ) is decided in the negotiation phase ( with Content-Type/Accept headers ).

Example Let's say we've got an operation UserCreate with POST /users path.

We define two versions of the User types.

UserV1 with media type: application/vnd.custom.user+json;version=1

type UserV1 struct {
	FirstName string `json:"first_name" required:"true" doc:"The user's first name."`
	LastName  string `json:"last_name" required:"true" doc:"The user's last name."`
	Email     string `json:"email" required:"true" doc:"The user's email address."`
}

UserV2 with media type: application/vnd.custom.user+json;version=2

type UserV2 struct {
	FirstName string `json:"first_name" required:"true" doc:"The user's first name."`
	Age       int    `json:"age,omitempty" doc:"The user's age."`
}

Input/Output types

type InputV1 struct {
	Body struct {
		User UserV1 `json:"user" required:"true" doc:"The user data."`
	}
}

type InputV2 struct {
	Body struct {
		User UserV2 `json:"user" required:"true" doc:"The user data."`
	}
}

type OutputV1 struct {
	Body struct {
		User UserV1 `json:"user" doc:"The user data."`
	}
}

type OutputV2 struct {
	Body struct {
		User UserV2 `json:"created_user" doc:"The user data."`
	}
}

They are backward-incompatible with each other, and we want to serve both versions.

OAS From the OAS perspective, it would be smth like this:

...
openapi: 3.1.0
paths:
  /user:
    post:
      requestBody:
        content:
          application/vnd.custom.user+json;version=1:
            schema:
              $ref: "#/components/schemas/InputV1"
          application/vnd.custom.user+json;version=2:
            schema:
              $ref: "#/components/schemas/InputV2"
      responses:
        "200":
          content:
            application/vnd.custom.user+json;version=1:
              schema:
                $ref: "#/components/schemas/OutputV1"
            application/vnd.custom.user+json;version=2:
              schema:
                $ref: "#/components/schemas/OutputV2"
...

Question

Is there a way to define such an operation in the current Huma state and get versioning out of the box with all the Huma features ( OAS generation, validation, and so on )?

For example:

  • A client sends Content-type: application/vnd.custom.user+json;version=1 and Accept: application/vnd.custom.user+json;version=1 and Huma validates and processes the request against UserV1 type and uses it for the response.
  • A client sends Content-type: application/vnd.custom.user+json;version=2 and Accept: application/vnd.custom.user+json;version=2 and Huma validates and processes the request against UserV2 type and uses it for the response.
  • A client sends Content-type: application/json and Accept: application/json, and Huma validates and processes the request against the default type ( e.g., UserV2 ) and uses it for the response.

Thank you in advance.

superstas avatar Jul 15 '25 11:07 superstas