Skip to content

Client and Request Lifecycle

Contents | Previous: Streaming | Next: Redirect, Retry, and Cookies

After reading this chapter

This chapter establishes when HTTP call resources are reused and closed, how a request finishes, and where timeouts and options apply. Its creation code comes from each language's HttpClient tutorial.

A client is a reusable unit that holds a base URL and transport options. A builder creates the client; a request builder gathers an HTTP method, path, and body. A terminator is the final call that submits the gathered request and selects its response form.

1. Flow from Builder to Response

↗ 크게 보기

The client keeps the connection pool and defaults for requests to the same target service. A request builder belongs to one request, and its terminator submits that request.

2. One Client Is Reused per Service

One client per service is reused for multiple requests. Building a client per request recreates keep-alive and the connection pool. The language's resource-management mechanism closes the client when it is no longer needed.

const client = ZLinkHttpClient.create(clientBaseUrl).timeout(3000).build();

The example creates one client with a base URL and a three-second timeout, then closes it at the end of the program lifetime.

A Spot or channel handler uses a DI-provided client instead of creating one through the static factory. This boundary preserves connection-pool reuse across handlers and the framework execution context.

3. Each Response Form Has a Terminator

A terminator submits the request builder as an HTTP request. A typed response carries status, headers, and a JSON-decoded body; a raw response carries status, headers, and the body before JSON decoding. The same response form has different language spellings, and the names in the table identify the response role rather than the execution model of the calling site.

Response form C++ C#/.NET Java Kotlin Node/TypeScript
typed response HttpResponse<T> async<T>() Async<T>(ct?) submit(Class<T>) await(type) / await<T>() (suspend) submit<T>()
raw response async_raw() AsyncRaw(ct?) submitRaw() awaitRaw() (suspend) submitRaw()
decoded body T only fetch<T>() Fetch<T>(ct?) fetch(Class<T>) fetch<T>() (suspend) fetch<T>()
streaming download download(sink) DownloadAsync(sink, ct?) download(Consumer<byte[]>) awaitDownload(sink) download(sink)
callback completion async<T>(callback) Async<T>(callback) submit(Class<T>, callback) replaced by a suspend function submit<T>(callback)
gate return (DI server builder only) yield<T>() Yield<T>(ct?) yield(Class<T>) yield<T>() (suspend) yield<T>()
blocking (CLI and client scenarios only) submit_raw(), submit<T>() unavailable unavailable unavailable unavailable

4. Distinguish the Two Timeout Boundaries

The client timeout defaults to 3000ms; a request builder timeout changes the per-attempt timeout only for that request. A request with retry enabled applies this timeout to every attempt. There is no option that sets one deadline over all retries.

5. Asynchronous Completion Does Not Occupy the Caller

An asynchronous terminator does not occupy the caller thread or event loop while the network is pending. The language's asynchronous composition mechanism waits for completion. A blocking terminator exists only for C++ CLI and client scenarios; it cannot be used in a framework runtime execution context.

6. Client Options Have One Configuration Point

Option Default Meaning
baseUrl required base URL for every request path
timeout 3000ms per-attempt timeout
defaultHeader none, accumulated default header attached to every request
basicAuth off Basic authentication
bearerToken off Bearer authentication
maxResponseBodySize 16 MiB body limit applied after decompression too
trustCertificateFile system roots adds a trusted PEM certificate
clientCertificateFile off mTLS client certificate and key
followRedirects off; 5 when called without an argument automatic redirect limit
retry off; 0 attempts additional retry attempts
cookies off enables the cookie jar
proxy off http:// proxy URL
proxyBasicAuth off proxy Basic authentication
compression off requests gzip/deflate and decodes transparently

Authentication, TLS, and Proxy covers authentication and proxy options, Streaming covers streaming exceptions, and Redirect, Retry, and Cookie covers redirect and retry rules.

7. A One-Shot Is a Single Convenience Path

A client builder can start an HTTP method directly. This one-shot path creates its client when submitted and closes it after completion, so it does not reuse the connection pool. A one-shot request cannot be submitted again; resubmission fails with InvalidOperation. It fits a single administrative operation, while repeated and high-load calls use a reusable client.

8. Next Chapter

Redirect, Retry, and Cookie covers automatic redirect, retry, and cookie-jar rules.