diff --git a/.changeset/24043-http-request-body-tsdoc.md b/.changeset/24043-http-request-body-tsdoc.md new file mode 100644 index 0000000000..a0c326a171 --- /dev/null +++ b/.changeset/24043-http-request-body-tsdoc.md @@ -0,0 +1,12 @@ +--- +"@objectstack/spec": patch +--- + +docs(spec): `IHttpRequest.body`'s TSDoc says what a handler reads, and that reading it may refuse + +Clause-②: no + +- **What it is.** The parsed JSON document for `application/json`, or the parsed fields of a `multipart/form-data` or `application/x-www-form-urlencoded` form; `{}` when the request carries no body. +- **It may refuse.** An implementation that cannot parse the body, or does not read its media type, throws from the read instead of handing over an invented value. The standard transport (`@objectstack/plugin-hono-server`) does, and answers 400 `INVALID_REQUEST` itself, replacing whatever the handler wrote. So a handler must not catch the refusal and carry on. +- **Raw bytes.** A handler that needs them reads `rawBody()` and never reads `body`. +- **Unchanged:** the type (`body?: any`), every other member, and every runtime behaviour. This is prose in the shipped `.d.ts` only. diff --git a/packages/spec/src/contracts/http-server.ts b/packages/spec/src/contracts/http-server.ts index 09bfeb1d50..e822aaf80d 100644 --- a/packages/spec/src/contracts/http-server.ts +++ b/packages/spec/src/contracts/http-server.ts @@ -20,7 +20,23 @@ export interface IHttpRequest { params: Record; /** Request query parameters */ query: Record; - /** Request body (parsed — JSON or form data when applicable) */ + /** + * Request body, parsed by its declared content type: the parsed JSON + * document for `application/json`, or the parsed fields of a form + * (`multipart/form-data`, `application/x-www-form-urlencoded`). `{}` when + * the request carries no body. + * + * Reading it may REFUSE: an implementation that cannot parse the body, or + * that does not read the body's media type, throws from the read rather + * than hand over an invented value. The standard transport + * (`@objectstack/plugin-hono-server`) does, and answers the request itself + * with 400 `INVALID_REQUEST`, replacing whatever the handler wrote; so a + * handler must not catch the refusal and carry on, because anything it + * does after the catch acts on a request that has already been refused. + * + * A handler that needs the raw bytes (a file upload, a media type not + * listed above) reads {@link rawBody} and never reads `body`. + */ body?: any; /** Request headers */ headers: Record;