3.1 Messages and bodies
Everything in RS2 moves as a message. A service is a function from a message to a message (1.1); understanding the message model explains a lot of the runtime's behavior.
What a message is
A message is the familiar HTTP shape:
- a method (
GET,PUT, …) and a URL (path + query), - headers,
- a body, and
- a media type describing the body.
The same structure is used for requests, responses, and the in-flight value that flows through a pipeline. That uniformity is why steps compose: a response is a message a later step can act on.
Bodies: bytes or stream
A body is either materialized bytes or a stream. This matters for large
payloads: a file write streams from the client to disk without ever holding
the whole thing in memory, and a read streams back the same way. The runtime
only materializes (buffers fully) a body when an operation genuinely needs the
bytes — and even then it's capped (default 100 MB; an over-cap materialization
fails with payload_too_large/limit_exceeded rather than exhausting memory).
The practical upshot for you as a caller: large uploads and downloads are efficient by default, and you don't manage buffering.
Media types are mandatory and meaningful
Every body carries a media type — it's not optional metadata. The file
service derives it from the resource's extension (never by sniffing content); an
unknown extension becomes application/octet-stream. The data service uses
application/json, and when a record has a schema it includes a schema pointer
in the Content-Type (e.g. application/json; schema="…/.schema.json").
Because media types are explicit, content negotiation and downstream handling are predictable rather than guessed.
Provenance: can this body be replayed?
A subtle but important property the runtime tracks is a body's provenance — roughly, whether it can be read again:
- Materialized — the bytes are in hand and can be re-read.
- Replayable — the source can be re-fetched if needed.
- Ephemeral — a one-shot stream that can't be rewound.
You rarely set this yourself, but it's why some pipeline behaviors differ for streaming bodies: a segment whose input is a large, ephemeral stream can't be snapshotted, so it runs at most once (Part 7's segments). When you see "streaming bodies aren't retried," provenance is the reason.
Why this matters downstream
Three later behaviors fall out of this model:
- Conditional requests (
ETag/If-None-Match) work because stores version every resource — see 4.2. - Schema-carrying content types let clients discover validation rules — 4.5.
- Materialization caps and streaming retry limits are limit/pipeline behaviors — Parts 7 and 9.
Next: how messages get routed to the right service.
← Part 2 — Getting Started · Manual home · Next: 3.2 Tenants and mounts →