Response Rules¶
Contents | Previous: Redirect, Retry, and Cookies | Next: Error Handling
View in another language — C++ · C#/.NET · Java · Kotlin · Node/TypeScript
After reading this chapter
You can distinguish status handling by response shape, JSON decoding and body limits, and the boundary of decompression.
The processing path changes according to what a caller needs from the same HTTP response. A typed response is a JSON body decoded into an application type; a raw response preserves status, headers, and the original body. Use raw when an error payload or headers need direct handling.
1. Response paths by status¶
| Response shape | 2xx/3xx | 4xx/5xx | Body |
|---|---|---|---|
| Raw response | Returns successfully | Returns successfully | Provides the original body |
| Typed response | Returns successfully | InternalFailure |
Provides the JSON-decoded value |
| Body-only response | Returns successfully | InternalFailure |
Provides only the decoded body |
| Download sink | Returns successfully | Returns like raw | Delivers only final-response bytes to the sink |
Typed and body-only responses do not expose a body when status is 400 or higher. Select raw when an error payload is required. HEAD and 204 have an empty successful body; on typed paths this becomes the language's absent value.
2. JSON decoding failures and body limits¶
When a typed response cannot decode its JSON body into the target type, it fails with protocolError. This is independent of HTTP status: even a successful status cannot produce a typed result when the response shape is wrong.
The default limit for an ordinary response body is 16 MiB. Exceeding it while accumulating the body produces Rejected. A download sink has the same accumulated-size limit, but receives raw bytes and does not apply the decompression in the next section.
3. Reading a compressed response¶
Compression is off by default. The tutorial enables it and confirms that a typed response no longer exposes the content-encoding header.
const compressed = await ZLinkHttpClient.create(clientBaseUrl)
.compression()
.get(`/rooms/${room}`)
.submitRaw();
console.log(
`compressed response: ${compressed.status} encoding-removed ${compressed.headers['content-encoding'] === undefined}`
);
Enabling compression adds Accept-Encoding: gzip, deflate. gzip and deflate bodies are transparently decompressed, and content-encoding plus related length headers are removed. Typed and raw responses therefore read the body as if it had not been compressed. The 16 MiB limit applies after decompression, so a small compressed response that expands too far ends with Rejected. A damaged compressed body produces protocolError.
A download sink does not decompress. The sink receives exactly the compressed bytes sent by the server. Select a normal response instead when decompressed content is required.
4. When to select the raw body¶
A raw response preserves status, headers, and body, so it suits direct handling of an API error payload, content type, or a status that should not follow redirects. When JSON has a stable shape and only a successful body is needed, a typed or body-only response performs decoding and status checking together.
5. Common problems¶
| Symptom | Cause |
|---|---|
| A 404 or 500 payload is unavailable from a typed response. | Typed and body-only paths turn status 400 or higher into InternalFailure. |
| A typed call fails despite a successful status. | The JSON body could not decode into the target type, producing protocolError. |
| A small gzip response exceeds the body limit. | The limit applies to the decompressed body size. |
| A downloaded file looks like gzip bytes. | A download sink does not decompress. |
6. Next¶
- Downloading or uploading an uncompressed stream — Streaming
- Failure kinds and deciding on a new operation — Error Handling