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

Builders

What Is a Builder?

A builder collects configuration through chained method calls and hands back a finished object when you call build(). You might have already used one in other frameworks or libraries. In general, they look like:

const car = Car .builder() // Get a car builder .engine("5.2L-FSI-v10") // Set the engine .wheels("19x9_OZ_LEGGERA_HLT") // Set the wheels .color("SUZUKA_GREY") // Set the color .otherMethods(/* other args */) // Set some other configurations .build(); // Build the car using the configurations car.doSomething(); // Do something with the car

In Drash, they look like:

const app = Application .builder() // Get an HTTP app builder .resources(Users, Coffees) // Set the resources in the app .build(); // Build the app app.handle(request); // Make the app handle a request

Drash hands you a builder instead of a constructor so that each piece of configuration is named at the call site. A constructor would put the same information in a positional argument list or an options object, where resources is a property you have to look up rather than a method you call.

Every builder in Drash shares one shape: a build() method that returns the finished object (aka product). That shape is the IBuilder interface.

build() Is the Last Call

Every method on a builder except build() returns the builder. Those calls are order-independent — the two lines below produce the same group:

ResourceGroup .builder() .middleware(Auth) .prefix("/api/v1") .resources(Users) .build(); // => Built object is the same as below ResourceGroup .builder() .prefix("/api/v1") .resources(Users) .middleware(Auth) .build(); // => Built object is the same as above

build() is the exception. Calling build() returns the object rather than the builder, so it ends the builder method chain and no further build configurations follow it.

build() is also where a builder checks that it has what it needs. This is a sanity check to ensure the finished object works properly during runtime instead of erroring out

For example, the HTTP module’s application builder throws an error if it provided an incorrect URLPattern-like class. You see this at startup, not on the first request that happens to reach the issue. In practice you should not hit it because the HTTP module’s Application.builder() provides the URLPattern class for you under the hood (see below). It is reachable only if you call the lower-level requestChain() factory function directly.

The Builders Drash Provides

BuilderYou get it frombuild() returns
HTTP Applicaiton BuilderApplication.builder()An HTTP request handler — call handle() on it
Resource Group BuilderResourceGroup.builder()An array of resource classes
Response Builderresponse()A Web Response
Request Builderrequest()A Web Request

Only the first two appear in a typical application. response() and request() are conveniences — a resource returning new Response(...) directly is equally valid.

For the methods each one exposes, see Builders and Resource Group in the reference.

Build Time, Not Request Time

Builders do their work once: when your application starts. All calls to build() do not happen again. There is no router re-deriving routes on each request, and no middleware stack being reassembled — by the time a request arrives, the objects it travels through already exist.

This is the benefit around Drash’s builders: startup does more work so that each request does less.

Last updated on