Skip to content

fix: generate requestBody for messages with oneOf and path params#234

Merged
sudorandom merged 1 commit intosudorandom:mainfrom
vitorbari:fix/missing-request-body-with-oneof-and-path-params
Mar 6, 2026
Merged

fix: generate requestBody for messages with oneOf and path params#234
sudorandom merged 1 commit intosudorandom:mainfrom
vitorbari:fix/missing-request-body-with-oneof-and-path-params

Conversation

@vitorbari
Copy link
Contributor

@vitorbari vitorbari commented Mar 3, 2026

Summary

Fix missing requestBody in generated OpenAPI specs for RPCs that use body: "*" with path parameters when the request message contains oneOf fields.

Problem

When a proto message has both regular fields and oneOf fields, MessageToSchema() restructures the schema by wrapping Properties and OneOf under an AllOf and setting Properties to nil:

  // schema.go lines 97-104
  if len(s.OneOf) > 0 && s.Properties.Len() > 0 {
      s.AllOf = append(s.AllOf,
          base.CreateSchemaProxy(&base.Schema{Properties: s.Properties}),
          base.CreateSchemaProxy(&base.Schema{OneOf: s.OneOf}),
      )
      s.Properties = nil
      s.OneOf = nil
  }

The body: "*" handling in paths.go then checks s.Properties != nil before generating the requestBody. Since Properties was moved into AllOf, this check fails and the entire request body is silently dropped.

For example, this proto:

  message UpdateRequest {
    string id = 1;       // path param
    string name = 2;     // body field
    oneof details {      // body oneOf
      Profile profile = 3;
      Settings settings = 4;
    }
  }

  rpc Update(UpdateRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      patch: "/resources/{id}"
      body: "*"
    };
  }

Previously generated an operation with no requestBody at all. After this fix it correctly generates a body with name and the profile/settings oneOf.

Test

Added a path_params test scenario with an UpdateRequest message that combines a path parameter, a regular field, and a oneOf group

When a message has both regular fields and oneOf fields,
MessageToSchema wraps them under AllOf and sets Properties to nil.
The body:"*" code path only checked s.Properties, so it skipped
generating the requestBody entirely for these messages.

Look for properties inside the AllOf entries when s.Properties is nil,
and check for AllOf/OneOf content when deciding whether to emit a
requestBody.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vitorbari vitorbari marked this pull request as ready for review March 3, 2026 11:08
@sudorandom sudorandom merged commit aac008e into sudorandom:main Mar 6, 2026
4 checks passed
livio-a pushed a commit to zitadel/zitadel that referenced this pull request Mar 6, 2026
# Which Problems Are Solved

1. `oneOf` variant sub-schemas generated from proto `oneof` fields
missing `type: "object"`. This causes fumadocs to skip rendering the
properties within each variant. Example:
https://zitadel.com/docs/reference/api/internal_permission/zitadel.internal_permission.v2.InternalPermissionService.CreateAdministrator


[Before](https://zitadel.com/docs/reference/api/internal_permission/zitadel.internal_permission.v2.InternalPermissionService.CreateAdministrator):
<img width="977" height="823" alt="Screenshot 2026-03-06 at 09 56 38"
src="https://github.com/user-attachments/assets/54ddbbbb-f36b-4a2a-96af-13b3da41de3b"
/>


[After](https://docs-git-bump-protoc-gen-connect-openapi-version-zitadel.vercel.app/docs/reference/api/internal_permission/zitadel.internal_permission.v2.InternalPermissionService.CreateAdministrator):
<img width="964" height="1021" alt="Screenshot 2026-03-06 at 09 56 47"
src="https://github.com/user-attachments/assets/a461c4b5-44fe-487b-b4d2-8af47d407d3e"
/>


2. missing requestBody for messages with oneOf and path params. Example:
https://zitadel.com/docs/reference/api/user/zitadel.user.v2.UserService.UpdateUser


[Before](https://zitadel.com/docs/reference/api/user/zitadel.user.v2.UserService.UpdateUser):
<img width="994" height="883" alt="Screenshot 2026-03-06 at 09 59 03"
src="https://github.com/user-attachments/assets/824f4154-3270-45d7-9af7-a28c7bdc7c44"
/>



[After](https://docs-git-bump-protoc-gen-connect-openapi-version-zitadel.vercel.app/docs/reference/api/user/zitadel.user.v2.UserService.UpdateUser):

<img width="978" height="1293" alt="Screenshot 2026-03-06 at 09 59 25"
src="https://github.com/user-attachments/assets/330c1204-ccce-402c-bccb-b27076198dcd"
/>

(fuma-nama/fumadocs#3063 will also be updated
with improved `oneOf` visualization in this case.)

# How the Problems Are Solved

By fixing `protoc-gen-connect-openapi` to correctly generate the OpenAPI
docs.

# Additional Changes

n/a

# Additional Context

sudorandom/protoc-gen-connect-openapi#233
sudorandom/protoc-gen-connect-openapi#234
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API reference missing request body for endpoints with oneOf fields and path parameters

2 participants