@metreeca/gate - v0.12.0
    Preparing search index...

    Module driver

    Model-driven resource drivers.

    Serves resources held in a @metreeca/keep store, so that an Express application exposes a REST API for the resources a shape describes. The application enables the HTTP methods each route supports, with no handler to write.

    server(store)
    .use("/products/", driver(Products).lookup().create())
    .use("/products/:id", driver(Product).lookup().update().delete());

    Drivers serve the store the application was created with, and identify resources by the base the server was started with, so that every driver of an application shares them. A request reaching a driver on an application created with no store fails, and the error middleware of the surrounding stack answers it.

    IRIs sharing the scheme and authority of the base are exchanged in root-relative form. Response bodies and Location headers always state them so, and request bodies may state them so. Decoding hooks and validation only ever see absolute IRIs. Without a base, the scheme and host each request was received on stand in for it.

    Each driver is an Express handler mounted with use(), like a nested router. It serves the path it is mounted on, with or without a trailing slash, and passes requests for paths below it on to the next handler of the stack, so that the drivers of a container and of its items may be mounted on nested paths. Methods are enabled Express style, on the driver itself, and may be enabled after the driver is mounted; enabling the same method again replaces its options. Once at least one method is enabled, every request for the mount path is answered by the driver itself:

    • HEAD through the GET handler, where GET is enabled
    • OPTIONS with 204 No Content and an Allow header listing the methods enabled
    • any other method not enabled with 405 Method Not Allowed and the same Allow header

    A driver with no method enabled passes every request on to the next handler of the surrounding stack.

    Request bodies

    Drivers read JSON request bodies on their own, so an application serving only drivers needs no body parser. A body must be stated as application/json: other media types are answered with 415 Unsupported Media Type, and a body that is not valid JSON with 400 Bad Request. Where an upstream express.json() has already parsed the body, the driver uses that result instead of reading the request again, so the limits that parser enforces still apply.

    Warning

    Drivers set no limit on the size of the bodies they read, so an untrusted client may send arbitrarily large ones. To bound them, mount express.json({ limit }) ahead of the drivers, which then reuse the body it parses:

    server(store)
    .use(express.json({ limit: "1mb" }))
    .use("/products/", driver(Products).lookup().create());

    Failures

    Drivers answer the failures of a request on their own:

    • 400 Bad Request with the error message, where the query component or the JSON body cannot be decoded
    • 415 Unsupported Media Type with an Accept header, where a body is not stated as application/json
    • 422 Unprocessable Content with the violation trace as JSON, where a template or a body fails validation against the shape, with the error message, where client criteria cannot be combined with those of the server template, or with the trace or message of the rejection, where the store rejects the request

    Any other error is passed on to the error middleware of the surrounding stack.

    Type Aliases

    LookupHooks

    Retrieval hooks, as accepted by the lookup() method of a Driver.

    WriteHooks

    Write hooks, as accepted by the create() and update() methods of a Driver.

    Driver

    Model-driven resource driver.

    Functions

    driver

    Creates a resource driver.