Handling Requests
What a resource receives, and how to read from it
Overview
Every chain built by the HTTP module’s Application.builder() runs a RequestParamsParser handler before it calls your resource. That handler attaches a non-enumerable params object to the request, and that object is how you read the two kinds of parameters a URL can carry:
- path params — the
:namesegments declared in a resource’spathsproperty; and - query params — the
?name=valuepairs a client appends to the URL.
You do not add the parser yourself. It is one of the handlers the request chain wires up for you, so params is present on every request that reaches a resource.
Recommended Reading
- Read the concepts on HTTP applications
- Read Creating a Resource to see how paths are declared
Objectives
To gain familiarity with:
- what a resource’s HTTP methods receive;
- typing the request so your editor knows
paramsexists; and - the two methods
paramsprovides.
What a Resource Receives
An HTTP method receives whatever was passed to app.handle(). On runtimes with Web Request/Response that is the Request object itself. On Node it is the context object you built. In both cases the chain has already attached params to it by the time your method runs.
Typing the Request
params is attached at runtime, so a plain Request type does not know about it. Use the HTTPRequest type the HTTP module exports and your editor will autocomplete both methods:
Deno
import {
Resource,
type HTTPRequest,
} from "npm:@drashland/drash/modules/http.native.js";
class Users extends Resource {
public paths = ["/users/:id?"];
public GET(request: HTTPRequest) {
// `request.params` is known to the type checker here
const id = request.params.pathParam("id");
const sort = request.params.queryParam("sort");
return new Response(`id=${id} sort=${sort}`);
}
}HTTPRequest is a type, not a class. Import it with type so it is erased at build time rather than becoming a runtime import.
The params Object
It provides exactly two methods:
| Method | Returns | Notes |
|---|---|---|
pathParam(name) | string | undefined | From the matched URLPattern |
queryParam(name) | string | undefined | From the query string — see the caveat on Query Params |
Both return undefined for a name that was not matched rather than throwing. That is what makes optional params usable: you check the value instead of catching an error.
const id = request.params.pathParam("id");
if (!id) {
throw new HTTPError(Status.BadRequest, "id is required");
}params is defined as non-enumerable, so it does not show up in Object.keys(request) or JSON.stringify(request). It is there — it just stays out of the way of anything that walks the request’s own properties.