Skip to Content
Drash v3 is in beta. APIs may change.
ReferenceModuleshttp.native

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

ExportKindReference
ApplicationclassBelow
ResourceclassCreating a Resource
MiddlewareclassMiddleware
ResourceGroupclassResourceGroup
HTTPErrorclassHTTPError
HTTPRequesttypeThe 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:

#HandlerWhat it does
1RequestValidatorRejects inputs lacking a readable url or method field.
2ResourcesIndexMatches input.url against each resource’s paths using URLPattern or a polyfilled URLPattern.
3ResourceNotFoundHandlerThrows HTTPError(404) when the ResourcesIndex handler cannot find a matching resource.
4RequestParamsParserDefines a non-enumerable params property on the request. Access it via request.params.
5ResourceCallerInvokes 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 easy

The 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.

Last updated on