Skip to content

feat: resumable upload support in gapic-generator - #1357

Draft
viacheslav-rostovtsev wants to merge 7 commits into
googleapis:mainfrom
viacheslav-rostovtsev:implement_resumable_upload_generator
Draft

viacheslav-rostovtsev wants to merge 7 commits into
googleapis:mainfrom
viacheslav-rostovtsev:implement_resumable_upload_generator

Conversation

@viacheslav-rostovtsev

Copy link
Copy Markdown
Member

No description provided.

@viacheslav-rostovtsev
viacheslav-rostovtsev requested a review from a team as a code owner September 21, 2026 17:43
Generate a resumable upload surface for RPCs that perform media uploads.
Such an RPC no longer returns a response message: it returns a
::Gapic::ResumableUpload handle, and the upload begins when the caller
starts or resumes it.

- Gapic::Model::Method::ResumableUpload detects upload RPCs from a match
  table (exact prefixes plus a versioned form for ads) and rejects RPCs
  the surface cannot support: streaming, paginated, long-running, and
  bindings that are not a POST with a body.
- Each service with upload RPCs gets a <Service>::ResumableUploadStub,
  emitted for both transports because an upload always travels over
  REST. It owns the REST client stub, the initiation-request
  transcoders, and the credentials error a client built from a gRPC
  channel has to raise when an upload is attempted.
- Both clients build the stub in their constructor and dispatch upload
  RPCs to the handle. The REST service stub no longer carries a call
  method or transcoder for them.
- Documentation states the split between the initiation request, which
  the call's timeout and retry policy cover, and the upload itself,
  which they do not.
- Upload RPCs are excluded from the generated client tests and covered
  by a dedicated generated test file instead.

The .with_bindings chain is extracted into a shared partial so the REST
service stub and the upload stub emit it identically; the extraction is
output-neutral for every existing golden.
An upload RPC returns a handle rather than a response, so the snippet
that called it and printed the result no longer describes the surface.
Name the call result `upload`, then start the upload and print what that
returns.

Snippet composition is presenter-driven, so this covers the standalone
snippet file and the inline @example together.
@viacheslav-rostovtsev
viacheslav-rostovtsev force-pushed the implement_resumable_upload_generator branch from 5528dd4 to dfb1828 Compare September 21, 2026 17:50
@viacheslav-rostovtsev
viacheslav-rostovtsev marked this pull request as draft September 21, 2026 17:50
Upload methods on a gRPC client travel over REST, so x-goog-api-client must report rest/<version> rather than the grpc/<version> default of Gapic::Headers.x_goog_api_client.
An upload method only constructs a ::Gapic::ResumableUpload handle and performs no RPC or HTTP request, so the flavor rescue block is dead code. Runtime errors are wrapped by the handle's error_handler.
The generated test called the real transcoder with placeholder field values, which cannot satisfy multi-segment path templates and yields query params for non-* body bindings. Stubbing the transcoder pins the upload stub's own contract (URL prefix, query-string folding, [uri, body]) independently of the RPC's bindings.
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