Repository navigation
fix(sdk): preserve optional TypeScript request bodies - #5383
Conversation
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Body optionality contract api/spec/packages/typespec-typescript/src/sdk-operations.ts, api/spec/packages/typespec-typescript/src/request-types.ts |
The generator records body optionality and uses it to produce optional body fields and body-only request types. |
Generated request signatures and validation api/spec/packages/typespec-typescript/src/sdk-files.ts, api/spec/packages/typespec-typescript/test/optional-body.test.ts |
Generated functions and SDK facades accept omitted bodies for body-optional operations. Generated validation runs only when an optional body is defined. Compiler tests check generated output for optional and required bodies. |
JavaScript client optional bodies api/spec/packages/aip-client-javascript/src/models/operations/*, api/spec/packages/aip-client-javascript/src/funcs/*, api/spec/packages/aip-client-javascript/tests/validation.spec.ts, api/spec/packages/typespec-typescript/templates/tests/validation.spec.ts |
Selected customer and feature request bodies are optional. Their client functions skip validation when serialization returns no body. Tests cover omitted and supplied bodies, invalid input, and a still-required body. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Possibly related PRs
- openmeterio/openmeter#5381: Adds an operation with an optional TypeSpec request body and identifies the generated TypeScript request body as incorrectly required.
Suggested labels: area/api, kind/bug, release-note/bug-fix
Suggested reviewers: tothandras, borosr
Merge Risk: 
Minimal · up to 47658
-
No actionable merge-blocking risk remains in the reviewed change.
Pre-merge checks: 
4
Finishing Touches
-
📝 Generate docstrings
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
tothandras
left a comment
There was a problem hiding this comment.
Looks good. I checked the server side: reset-customer-entitlement-usage, void-credit-grant and query-feature-cost all decode with request.ParseOptionalBody, which treats an empty body (EOF) as "no body". So when the SDK leaves the body out, the server gets the call it expects. Validation is still skipped only for optional bodies, and the createMeter(undefined) test shows required bodies are still checked.
Two small, non-blocking notes are inline. CI also still needs a release-note/* label (release-note/bug-fix fits).
| httpOp.parameters.body?.type !== undefined || bodyOverrides.has(base), | ||
| bodyOptional: | ||
| !bodyOverrides.has(base) && | ||
| (httpOp.parameters.body?.property?.optional ?? false), |
There was a problem hiding this comment.
Is the !bodyOverrides.has(base) guard needed? The CSV @sharedRoute variant declares no body, so body?.property?.optional would already give false there. On the JSON variant, the guard makes an override body required even if the spec marks it optional. That's fine for query-meter today, but if it's deliberate, a short comment would help. If it isn't, dropping the guard keeps one rule for every operation.
| optionalOnly(@body request?: Options): void; | ||
| @post @route("/required") @operationId("required-widgets") | ||
| required(@body request: Options): void; | ||
| } |
There was a problem hiding this comment.
Nit: requestDecl emits a third shape this fixture doesn't cover: an optional body together with query params and no path (AcceptDateStrings<{ body?: X } & Query>). In that shape req/request stays required, and bodyValue is req.body. An extra op such as @post @route("/optional-query") optionalQuery(@query q?: string, @body request?: Options): void; would lock that in.
…ing optional bodies Shared-route body overrides no longer force a required body; the declared body's optionality applies to every operation. Generated output is unchanged. Add a fixture operation with an optional body plus query parameters to lock in the remaining request shape.
Overview
The TypeScript SDK requires bodies that TypeSpec declares optional, and strict request validation rejects calls that omit them. Preserve body optionality in request types and facade arguments, and validate optional bodies only when present. Required bodies retain their existing validation.
Regenerated SDK output corrects entitlement usage resets, credit grant voiding, and feature cost queries. Regression tests cover omitted bodies with validation enabled and disabled, provided-body mapping and validation, and missing required bodies.
Notes for reviewer
This branch starts directly from
mainand is independent of the invoice-charges endpoint PR. Both v3 SDKs were regenerated; Go already handles optional bodies, so its generated output is unchanged.Validation passed:
make test-go-sdk).Affected v3 generation and formatting completed successfully. Full
make gen-apistopped in the unrelated legacy Python generator because its local virtual-environment executable is missing.Summary by CodeRabbit


Confidence Score: 5/5
The PR appears safe to merge; no blocking issues were found.Summary
Preserves optional TypeScript request bodies in generated request types and method arguments.
No actionable new issues or repository-rule violations were found. Tests were not run during this review.
Reviews (2) · Last reviewed commit: "refactor(sdk): derive body optionality u..." · Reviewed by Greptile