Skip to content

feat(server): describe batch binary responses with a dedicated content type - #1761

Merged
dinwwwh merged 1 commit into
middleapi:mainfrom
dinwwwh:claude/batch-streaming-content-type-c4ba7f
Aug 2, 2026
Merged

feat(server): describe batch binary responses with a dedicated content type#1761
dinwwwh merged 1 commit into
middleapi:mainfrom
dinwwwh:claude/batch-streaming-content-type-c4ba7f

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Aug 2, 2026

Copy link
Copy Markdown
Member

Batch responses that use the length-prefixed binary framing — streaming mode, and buffered mode when a sub-response carries binary — now advertise application/vnd.orpc.batch instead of falling back to application/octet-stream. Batch traffic is now distinguishable from ordinary file transfers in proxy logs, CDN rules, and dev tools, where before it was indistinguishable from any other opaque byte stream.

application/octet-stream means "unknown bytes" and was never chosen for batch — it is what the adapter fills in for any ReadableStream body with no content type set. The framing is a format oRPC defines, so it gets a name.

Compatibility

Nothing changes on the wire. Clients resolve the batch body from the standard-server hint (octet-stream / file), not from content-type, so old clients read new servers and new clients read old servers. Compression behavior is also unchanged: the new type sits outside the compressible allow-list, exactly like the old one, so batch bodies are still passed through untouched.

A +json suffix was considered and rejected — it would assert the whole body is JSON (it is binary length prefixes wrapping JSON, sometimes with raw binary appended), and it would pull streaming batches into CompressionStream, which does not sync-flush per chunk and would hold frames back instead of delivering them as each sub-request completes.

The all-JSON buffered path is untouched and still serializes as application/json. In streaming mode the plugin's content type wins over the headers option, matching buffered mode, which already hardcodes the type on the Blob.

Testing

Both framing paths assert the new header. Full root suite passes (2772 passed, 41 skipped), along with pnpm type:check across all packages and pnpm lint.

…t type

Batch responses that use the length-prefixed binary framing fell back to
`application/octet-stream`, which says "unknown bytes" for a format oRPC
defines. Advertise `application/vnd.orpc.batch` instead so logs, proxies
and dev tools can tell batch traffic apart from file transfers.

Decoding is unaffected: clients resolve the body from the `standard-server`
hint, not content-type.
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
orpc Ready Ready Preview Aug 2, 2026 1:55am

@pkg-pr-new

pkg-pr-new Bot commented Aug 2, 2026

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@1761

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@1761

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@1761

@orpc/client

npm i https://pkg.pr.new/@orpc/client@1761

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@1761

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@1761

@orpc/experimental-effect

npm i https://pkg.pr.new/@orpc/experimental-effect@1761

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@1761

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@1761

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@1761

@orpc/next

npm i https://pkg.pr.new/@orpc/next@1761

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@1761

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@1761

@orpc/pinia-colada

npm i https://pkg.pr.new/@orpc/pinia-colada@1761

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@1761

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@1761

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@1761

@orpc/server

npm i https://pkg.pr.new/@orpc/server@1761

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@1761

@orpc/swr

npm i https://pkg.pr.new/@orpc/swr@1761

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@1761

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@1761

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@1761

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@1761

commit: db48a31

@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 25 untouched benchmarks


Comparing dinwwwh:claude/batch-streaming-content-type-c4ba7f (db48a31) with main (7480727)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (28d6003) during the generation of this report, so 7480727 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • BATCH_CONTENT_TYPE constant — a new application/vnd.orpc.batch content type exported from the batch plugin, used to describe batch responses that carry the length-prefixed binary framing.
  • Buffered binary path — the Blob type changes from application/octet-stream to the new constant. No behavioral change: toFetchBody always overwrites the content-type header with the Blob's type, so the old and new code are indistinguishable at the adapter layer.
  • Streaming path — the content-type header is now explicitly set on the response (previously it defaulted to application/octet-stream from the adapter's ??= fallback). The new constant wins over any user-provided headers option for consistency with buffered mode.
  • Compression — the new type is not in the compressible allow-list regex, preserving the existing behavior of not compressing batch binary payloads.
  • Tests — both the buffered-binary and streaming test cases assert the new content-type header.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit f53bafa into middleapi:main Aug 2, 2026
12 checks passed
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.

1 participant