http.native
The native entry point, modules/http.native.js. It hands the chain the runtime’s own
global URLPattern.
import { Application, Resource } from "@drashland/drash/modules/http.native.js";Use it where the runtime implements URLPattern — Deno and Cloudflare Workers. Where it
does not, use http.polyfill, which exports the same
surface and differs only in the URLPattern class it injects.
Exports
| Export | Kind | Reference |
|---|---|---|
Application | class | Below |
Resource | class | Creating a Resource |
Middleware | class | Middleware |
ResourceGroup | class | ResourceGroup |
HTTPError | class | HTTPError |
HTTPRequest | type | The request shape a resource method receives |
The Application class below is declared in this file and in http.polyfill.js. Its API is
identical in both.
Application
.builder()
Returns a builder preconfigured with handlers.
import { Application } from "@drashland/drash/modules/http.native.js";
const app = Application
.builder()The preconfigured handlers are added in this order:
| # | Handler | What it does |
|---|---|---|
| 1 | RequestValidator | Rejects inputs lacking a readable url or method field. |
| 2 | ResourcesIndex | Matches input.url against each resource’s paths using URLPattern or a polyfilled URLPattern. |
| 3 | ResourceNotFoundHandler | Throws HTTPError(404) when the ResourcesIndex handler cannot find a matching resource. |
| 4 | RequestParamsParser | Defines a non-enumerable params property on the request. Access it via request.params. |
| 5 | ResourceCaller | Invokes resource[METHOD](request) (e.g., UsersResource.GET(request)). |
The order is not configurable through the builder. What you control is the set of resources or resource groups you provide. For example:
import { Application } from "@drashland/drash/modules/http.native.js";
const app = Application
.builder() // Assembles all handlers above
.resources(/* ... */) // Your resources come after so they can be called by `ResourceCaller`
.build() // Builds the chain in the above order.resources()
Registers resource classes with the chain. Pass classes, not instances — Drash constructs them under the hood. For example:
// Good
import { Resource } from "@drashland/drash/modules/http.native.js";
class Home extends Resource { /* ... */ }
const app = Application
.builder()
.resources(Home)
.build();// Bad
import { Resource } from "@drashland/drash/modules/http.native.js";
class Home extends Resource { /* ... */ }
const app = Application
.builder()
.resources(new Home()) // <--- DO NOT DO THIS
.build();Calling .resources() more than once replaces the set rather than appending. Pass everything in one call.
.urlPatternClass()
Overrides the URLPattern implementation. By default, the native and polyfill modules call this for you, but you can call it and pass in your own implementation. For example:
import { Application } from "@drashland/drash/modules/http.polyfill.js";
import { CustomUrlPattern, ExecResult } from "@drashland/drash/standard/polyfill/CustomURLPattern.js";
class MyCustomURLPatternClass extends CustomUrlPattern {
override exec(url: string): ExecResult | null {
/* Your URLPattern implementation */
return null;
}
}
const app = Application
.builder()
.urlPatternClass(MyCustomURLPatternClass) // Overrides the default implementation
.build();Use the polyfill module if you want to override the URLPattern implementation. If you use the native module, it will attempt a global URLPattern call and that could cause an error.
.build()
Wires the handlers together and returns the head of the chain.
app.handle(input)
Runs a request through the chain.
import { Application, Resource } from "@drashland/drash/modules/http.native.js";
class IndexResource extends Resource {
public paths = ["/"];
public GET(request: Request) {
return new Response("Oh so easy");
}
}
const app = Application
.builder()
.resources(/* your resources */)
.build();
const response = await app.handle<Response>(new Request("http://localhost:1447/"));
// => Oh so easyThe type parameter is the value you expect back — it is what the resource method returned, passed through unchanged. Drash does not construct it.
The app.handle(input) method’s input argument requires a fully qualified url and HTTP method. It can be a Web Request, or a plain object carrying whatever your resources need:
// Example of a context object being used in Node
const context = {
url: `http://${hostname}:${port}${request.url}`,
method: request.method,
request, // IncomingMessage
response, // ServerResponse
}
app.handle(context);// A Web Request already includes a `url` and `method` field,
// so it can be passed as is
const request = new Request("http://localhost:1447")
app.handle(request);Errors
The returned promise rejects on any error raised in the chain. Always attach a .catch() block — see HTTPError.
import { Application, Resource } from "@drashland/drash/modules/http.native.js";
class IndexResource extends Resource {
public paths = ["/"];
public GET(request: Request) {
throw new Error("Error from GET"); // Throw an error to exercise the `.catch()` block
}
}
const app = Application
.builder()
.resources(/* your resources */)
.build();
const response = app
.handle<Response>(new Request("http://localhost:1447/"))
.catch((error) => {
//
// The `error` will be the `Error from GET` error thrown in `IndexResource`
//
// Do some error handling here
//
})Concurrency
One chain instance handles concurrent requests. Build it once at module scope and reuse it; do not build per request.
Resources are constructed by the chain, so do not store per-request state on this in a resource or middleware. State kept on the instance is shared across every in-flight request.