Hitchy's API

In this topic you learn how to access Hitchy's API in components of your application. It provides a detailed introduction of features exposed in that API.

Regarding request handling, there is an introduction of special context for every request handler and additional properties and methods provided as part of request and response descriptors provided as arguments there.

Gaining Access

In a fully running application Hitchy's API is available

  • in every plugin complying with one of two patterns named common module pattern and common module function pattern,
  • in any function invoked on routing a request, that is
    • inline functions used in routing configurations,
    • methods of a controller and
    • methods of a policy.

Using Common Module Pattern

Plugins and components discovered by Hitchy are (consisting of) modules that may export an API as usual:

module.exports = {
    create() {
        // add some code here
    },
    customFunction() {
        // add some code here
    }, 
};

This example shows a software module that's exposing two functions to be its API the usual way.

Hitchy's core supports so called common module pattern when discovering plugins and their components.

Discovering Plugins?

In Hitchy discovering a plugin is different from requiring it. The term discovery refers to Hitchy's capability of automatically loading a plugin during bootstrap. In opposition to that any code of your application may still require() modules the usual way though this is going to have some negative side effects for modules relying on common module pattern.

The common module pattern is a convention allowing any complying module to export a function instead of its API. This function is invoked by Hitchy's bootstrap code to retrieve the actual API of the module:

module.exports = function( options ) {
    const api = this;

    return {
        create() {
            // add some code here
        },
        customFunction() {
            // add some code here
        }, 
    };
};

This is the counterpart of same module as before. But this time it is relying on the common module pattern mostly to gain access on Hitchy's API. During discovery of plugins and components any function exported from either module is invoked with Hitchy's API provided as this and global options describing runtime context and arguments passed on starting Hitchy in first argument.

Related Issues

On exporting an ES6 class in a module Hitchy might falsely consider this module to comply with common module pattern.

class MyServiceComponent {
    // TODO add methods here
}

module.exports = MyServiceComponent;

This results in error on Hitchy start regarding invoking your exposed class without operator new. As a fix you might need to wrap this class in a function to actually comply with common module pattern.

module.exports = function() {
    class MyServiceComponent {
        // TODO add methods here
    }

    return MyServiceComponent;
};

Alternatively you might add static property useCMP set false to prevent Hitchy from assuming this module is complying with common module pattern.

class MyServiceComponent {
    // TODO add methods here
    
    static get useCMP() { return false; }
}

module.exports = MyServiceComponent;

Returning Promise

When complying with common module pattern a module may return an instance of Promise rather than some API. In that case Hitchy is waiting for the promise to be resolved with the actually desired API.

Thus, when complying with common module pattern either module is capable of deferring bootstrap code of Hitchy and get all the opportunities required to deliver its export.

Passing Additional Information

Whenever Hitchy is supporting common module pattern it might intend to pass further information in addition to its API and options. This information will be provided as additional arguments following provided options.

Common Module Function Pattern

A similar pattern is supported e.g. when accessing some elements of a plugin's API and it is named common module function pattern. Just like common module pattern it is meant to support provision of a function to be invoked for generating some data instead of providing that data immediately. And any such function is invoked with Hitchy's API provided as this, Hitchy's options in first argument and any number of additional data provided in further arguments, too.

In opposition to common module pattern this isn't about a whole module to be load but just some property exported there. And for the containing module to be capable of complying with common module pattern using this pattern isn't quite as beneficial and commonly useful except for rare cases.

In Request Handlers

In request handlers the API is exposed in two different ways:

  1. Every request handler is invoked with this referring to some request context which is including reference on Hitchy's API in property api:

    function someRequestHandler( req, res ) {
        // access Hitchy's API via this.api here ...
    }
    
  2. Starting with v0.2.0 the API is exposed as property hitchy of given request descriptor as well. This enables use of arrow functions and helps with accessing the API in nested functions and callbacks more easily:

    ( req, res ) => {
        // access Hitchy's API via req.hitchy here ...
    }
    

Options

When talking about common module pattern before there was an argument passed providing so called Hitchy options.

Basically this is a set of parameters provided on invoking Hitchy. Usually this is done via Hitchy's CLI script. Thus, provided options are related to parameters provided on running CLI script. However, when testing Hitchy and its plugins it is possible to pass options from testing scripts as well.

hitchy /app --pluginFolder /some/different/path --debug

There are options recognized by Hitchy and some of those get qualified during bootstrap.

Additionally provided parameters are included with options available in common module pattern. That's why your application is implicitly capable of supporting custom CLI options for controlling its behaviour.

hitchy /app --useAuthProvider https://some.auth.provider.com

These are options recognized and/or managed by Hitchy:

options.projectFolder

This option is qualified during triangulation stage of bootstrap. It is addressing folder containing currently running application. When omitted current working directory is used by default.

CLI Parameter

When using Hitchy's CLI the related parameter is called --project.

options.hitchyFolder

This option is defined by Hitchy during triangulation stage of bootstrap. It is addressing folder containing Hitchy installation used to manage currently running application.

CLI Parameter

There is no related CLI parameter for using Hitchy's CLI script already requires to pick its installation folder.

options.pluginsFolder

This option is picking different folder containing all available plugins in a node_modules sub-folder. The project folder is used in case of omitting this option.

CLI Parameter

When using Hitchy's CLI the related parameter is called --plugins.

options.explicitPlugins 0.4.0+

This option is explicitly listing folders containing plugins and their local dependencies.

In opposition to more commonly useful option pluginsFolder this option is also checking the provided folder itself for implementing some plugin.

CLI Parameter

When using Hitchy's CLI the related parameter is called --plugin. It can be provided multiple times.

options.explicitPluginsOnly 0.4.0+

This boolean option can be set to limit discovery of plugins to those folders listed explicitly using option explicitPlugins.

CLI Parameter

When using Hitchy's CLI the related parameter is called --explicit-only.

options.debug

This boolean option is controlling whether debug output is desired or not. Basically this option affects Hitchy to always enable any logging facility.

CLI Parameter

When using Hitchy's CLI the related parameter is called --debug.

options.dependencies

This option is supported to select plugins current application depends on. It is replacing any such list of plugins read from application's own hitchy.json file. In addition it is limiting set of eventually available plugins.

CLI Parameter

When using Hitchy's CLI the related parameter is called --depend-on. It can be provided multiple times.

Configuration

During bootstrap Hitchy is shallowly reading Javascript files available in sub-folder config of your application as well as of any plugin. Either file is assumed to export part of resulting configuration:

exports.part = { ... };

Either file may comply with common module pattern e.g. to gain access on Hitchy's options and its API or to provide its configuration asynchronously by returning Promise.

module.exports = function( options ) {
    const api = this;

    return checkSomeSource()
        .then( info => {
            return {
                part: { ... },
            };
        } );
};

All files' exports are merged into one configuration object which is exposed at runtime as api.config in modules complying with common module pattern and as this.config in request handlers.

Rules For Naming Files

A configuration file's name

  • must not start with a full stop . and
  • must have extension .js.

Apart from that you may choose any name you like.

As a convention, though, there is another file for every first-level property of resulting configuration object with the filename matching that property's name. So, configuration for config.routes would be found in file config/routes.js and it is exporting related part of configuration like this:

exports.routes = { ... };

Order of Processing

For every plugin as well as the application itself all its configuration files are sorted by name and processed in resulting order. Application's files are processed after either plugin's configuration.

In either context a file named config/local.js is always processed last. It is meant to contain local-only customizations for all other files which are part of distributed application.

The structure of configuration depends on used plugins and it might include arbitrary information specific to your application, as well. However, some properties are supported by Hitchy's core and they are listed below:

config.policies

Hitchy's Routing Concept

Reading the introduction on Hitchy's routing is highly recommended.

This property is exposing routing declarations of policies. Policies can be declared in plugins as well as in application.

The supported format is mostly identical to the one supported for config.routes below.

See config.routes for additional information.

These are the differences between policies and routes:

  • When declaring policies targets are addressing policy components instead of controller components.

  • Targets of a route may be declared with optional suffix Controller. When declaring policy targets the supported suffix is Policy instead.

    config.routes = {
        "/some/route": "FooController.action",
    };
    config.policies = {
        "/some/route": "FooPolicy.action",
    };
    
  • When declaring routes every source must be linked with exactly one target. When declaring policies every source may also have a list of targets to be processed in order.

    bad:

    config.routes = {
        "/some/route": [
            "FooController.action",
            "FooController.altAction",
        ],
    };
    

    good:

    config.routes = {
        "/some/route": "FooController.action",
    };
    config.policies = {
        "/some/route": [
            "FooPolicy.action",
            "FooPolicy.altAction",
        ],
    };
    

config.blueprints

By intention, blueprints are supported in plugins, only.

Hitchy's Routing Concept

Reading the introduction on Hitchy's routing is highly recommended.

Declaration of blueprints is mostly equivalent to declaring routes in config.routes. In opposition to that blueprint declarations don't support separate lists per routing slot for there is only one slot for every plugin to declare its blueprint routes.

config.routes

Hitchy's Routing Concept

Reading the introduction on Hitchy's routing is highly recommended.

This property is exposing declarations of (terminal) routes.

Required

Routes are essential in Hitchy for it doesn't know how to handle incoming requests otherwise.

A set of routing declarations is given as Object or as a Map with the latter assuring certain order of processing, though this isn't quite as important in most cases due to Hitchy's routing preferring to match longer sources over shorter ones.

The set may be divided into slots for providing different sets per routing slot. Supported names for dividing declarations are early, before, after and late. By default, routing declarations are applied to before slot.

Providing declarations per routing slot is not supported for plugins.

Every single declaration is associating a routing source with a routing target.

  • The source is a string optionally selecting an HTTP method and mandatorily providing a pattern to be matched by a request's URL path. Patterns are supported using path-to-regexp.

    Here are some valid examples:

    "/some/path"
    "GET /api/:model/:id"
    "POST /api/:model/write/:id"
    "ALL /api/:model"
    

    When omitting provision of HTTP method it defaults to GET.

  • The target is given

    • as a regular function,

      "/some/route": function( req, res ) {
          // TODO implement this handler
      }
      
    • as an arrow function,

      "/some/route": ( req, res )  => {
          // TODO implement this handler
      }
      
    • as a string describing function exposed by available controller component or

      "/some/route": "FooController.action",
      "/some/route": "Foo.action", // equivalent for "Controller" is optional
      "/some/route": "Foo::action", // equivalent, just in case you prefer this notation style
      
    • as an object selecting function exposed by available controller component.

      "/some/route": { module: "FooController", method: "action" },
      "/some/route": { module: "Foo", method: "action" },
      "/some/route": { module: "Foo" }, // default for "method" is "index"
      "/some/route": { controller: "Foo" },
      "/some/route": { policy: "Foo" },
      

      controller and policy are just aliases for module supported for readability, only. They don't enable use of controllers in declaring policies or use of policies in declaring routes.

      Using this most complex syntax it is possible to declare additional arguments provided on invoking either request handler:

      "/some/route": { module: "Foo", method: "action", args: [
          "foo",
          "bar"
      ] },
      

      Those arguments are appended to the regularly provided arguments req, res and - in case of policies, only - next:

      // in api/controllers/foo.js
      exports.action = function( req, res, foo, bar ) {
          // foo will contain "foo" due to given declaration
          // bar will contain "bar" due to given declaration
      }
      

Regular Example

exports.routes = {
    "/some/route": "FooController.action",
    "/api/:model": { module: "ModelController" },
    "/api/:model/:id"( req, res ) {
        res.end( "Hello World!" );
    },
}

Example With Routing Slots

exports.routes = {
    early: {
        "/some/route": "FooController.action",
        "/api/:model": { module: "ModelController" },
    },
    after: {
        "/api/:model/:id"( req, res ) {
            res.end( "Hello World!" );
        },
    }
}

config.bodyParser

This property is exposing a function invoked with a buffer representing a request's raw body. It is invoked to parse this buffer for some contained information provided on invoking req.fetchBody() without any parameter. The function may return promise to deferredly deliver parsed content.

API Elements

Hitchy's API can be divided into several sections to be described here.

The following description assumes you know how to gain access on Hitchy's API in either situation, thus referring to it using just api.

api.config +0.3.0

All configuration of every available plugin as well as the application itself is loaded from Javascript files in either ones' config sub-folder and merged into a single configuration object which is exposed here.

api.config.$appConfig

Configuration provided in api.config always includes options exported by available plugins. If you need to access the application's own configuration - which is merged from reading all Javascript files in application's sub-folder config - this basically hidden property can be used.

This is the application's counterpart to either plugin's exposure of its pure configuration.

api.meta 0.4.0+

This property is exposing application's meta information which is similar meta information attached to every plugin. In both cases meta information can be considered another set of configuration. It can be distinguished, though, for

Application's meta information is read from two probable sources and merged into single set of data exposed here.

  1. An application may have its own hitchy.json file in its root folder.

    Example

    Assume to have a file named hitchy.json with following content:

    {
        "appendFolders": false
    }
    
  2. In addition its package.json file may provide meta information in special property hitchy.

    Example

    The same information given in example above could be provided via application's package.json file like this:

    {
        "name": "my-app",
        "version": "1.0.0",
        ...
        "hitchy": {
            "appendFolders": false
        }
    }
    

Data found in hitchy.json file is preferred over data found in package.json. Most meta information elements supported for plugins are ignored in context of application except for these:

api.runtime

This section of Hitchy's API is exposing a compilation of all components exposed by discovered plugins as well as current application itself. They are grouped by component type.

  • Controllers are exposed in api.runtime.controllers.
  • Policies are exposed in api.runtime.policies.
  • Models are exposed in api.runtime.models.
  • Services are exposed in api.runtime.services.

For the sake of flexibility and fault tolerance either group is exposed using its singular name as well. Thus using api.runtime.controller is equivalent to using api.runtime.controllers etc.

Change of API

Starting with version 0.3.0 the configuration isn't available as api.runtime.config anymore, but exposed as api.config.

api.data

Hitchy's API gets sealed after bootstrap has finished to prevent intended or accidental change of any exposed API.

This property is excluded in particular to provide a common space multiple components can use for saving and sharing data that's exceeding the lifetime of a single request.

api.log

This function is a generator for logging facilities. It is invoked with the name of a logging facility and returns another function which can be used to actually generate log messages on behalf of either facility.

Example

const AlertLog = api.log( "hitchy:plugin:tooling:alert" );
const DebugLog = api.log( "hitchy:plugin:tooling:debug" );

DebugLog( "got some configuration" );

AlertLog( "connection lost" );

Basically, facilities are supported to cluster your application's log and help with controlling what messages are actually logged or not making it more useful in either situation.

Environment-Based Control

Environment variable DEBUG is examined for providing a comma-separated list of facilities to be enabled.

DEBUG=hitchy:*,myapp:*,-*

Every item of that list

  • is a facility name to be logged,
  • may be prefixed with single dash - to explicitly exclude a matching facility from logging,
  • may contain asterisk * for matching multiple facilities to be enabled or disabled.

Naming Convention

Facility names should represent a hierarchy of facilities by extending the name of a superordinated facility with a colon and the intended facility's name.

Sticking to this pattern is beneficial on using asterisk * in logging control.

api.utility.file

This subsection provides helper functions used by Hitchy for accessing local file system.

Deprecation Warning

There is a more powerful package file-essentials and we consider to replace these functions with that package in a future release.

api.utility.promise

This subsection provides helper functions to simplify complex asynchronous processes using promises.

Deprecation Warning

There is a more powerful package promise-essentials and we consider to replace these functions with that package in a future release.

api.utility.object

This subsection provides helper functions for

  • deeply merging objects:

    target = api.utility.object.merge( target, sourceA, sourceB, ... )
    
  • deeply sealing objects:

    object = api.utility.object.seal( object )
    

    A callback may be provided in second argument to be called on every object to be sealed. It is invoked with breadcrumb of property names as array of strings and assumed to return boolean indicating whether either object should be actually sealed or not.

  • deeply freezing objects:

    object = api.utility.object.freeze( object )
    

    A callback may be provided in second argument to be called on every object to be frozen. It is invoked with breadcrumb of property names as array of strings and assumed to return boolean indicating whether either object should be actually frozen or not.

api.utility.case

This subsection provides functions for converting between different practices for writing names.

  • kebab-case to PascalCase:

    pascal = api.utility.case.kebabToPascal( "kebab-case" );
    
  • kebab-case to camelCase:

    camel = api.utility.case.kebabToCamel( "kebab-case" );
    
  • PascalCase to kebab-case:

    kebab = api.utility.case.pascalToKebab( "PascalCase" );
    
  • camelCase to kebab-case:

    kebab = api.utility.case.camelToKebab( "camelCase" );
    
  • camelCase to PascalCase:

    pascal = api.utility.case.camelToPascal( "camelCase" );
    

api.Client

This class is providing router client suitable for locally triggering request dispatching.

Obey The Naming!

This class is exposed using PascalCase name to comply with common rules of code style linters.

This client can be used to simulate requests for testing purposes, for improved request processing e.g. via websockets or for locally triggering request handlers e.g. for transparently rewriting requests or similar.

Example

const client = new api.Client( {
    method: "POST", 
    url: "/some/internal/url?foo=bar",
    headers: {
        "content-type": "text/json",
    },
} );

client.end( JSON.stringify( { some: "input" } ) );

return client.dispatch()
    .then( res => {
        if ( res.statusCode === 200 ) {
            return res.body()
                .then( body => JSON.parse( body.toString( "utf8" ) ) )
                .then( data => {
                    // TODO: process response
                } );
        }
    } );

This client simulates most parts of ClientRequest and ServerResponse. In addition method res.body() is provided to simplify retrieval of response body.

api.plugins

All discovered and loaded plugins are listed in this property. It is an object mapping a plugin's role (which might be different from its name!) into either plugin's API.

api.cmp

Signature: api.cmp( "./my/module", [ arg1, arg2 ] )

This method is loading selected module with support for common module pattern. Optionally provided arguments are passed in addition to options on invoking function exposed by selected module as part of common module pattern.

If selected module doesn't comply with that pattern it is loaded as usual.

api.cmfp

Signature: api.cmfp( someFunction, [ arg1, arg2 ] )

This method is invoking some function provided by reference with support for common module function pattern. This pattern is derived from common module pattern and is meant to invoke particular functions of plugins in a similar way.

Invoked functions are assumed to expect Hitchy's API as this and global options provided in first argument which is implicitly prepended by this method.

Request Context

On request handling routes are used to select handlers to be invoked. Those handlers areare functions invoked with this referring to a request context which is providing information related to currently dispatched request.

In a request handler like

function( req, res ) {
    // TODO add some handling code here
}

the request context is available using this.

this.request

This property is a reference on IncomingMessage describing current request to be handled. It is identical to the reference provided in first argument usually named req of either handler.

this.response

This property is a reference on ServerResponse for managing response to be sent. It is identical to the reference provided in second argument usually named res of either handler.

this.local

This object is provided for sharing volatile information between handlers involved in handling a particular request. This information is shared between policies and controllers participating in handling a request and gets dropped when handling request has finished.

this.api

Hitchy's API is provided in request context for simplified access.

this.config +0.3.0

This property is an alias for simplified access on api.config of Hitchy's API exposing current runtime configuration.

this.runtime

This property is an alias for simplified access on api.runtime of Hitchy's API exposing available components.

this.controllers +0.3.0

This is another alias for simplifying access on collection of available controllers.

Using this.controller is supported as well.

this.policies +0.3.0

This alias is simplifying access on collection of available policies.

Using this.policy is supported as well.

this.services +0.3.0

This alias is simplifying access on collection of available services.

Using this.service is supported as well.

this.models +0.3.0

This alias is simplifying access on collection of available models.

Using this.model is supported as well.

this.startTime

This property is exposing the time of handling current request has started as number of milliseconds since midnight of January 1st, 1970.

this.context +0.3.0

This property is a string naming the service hitchy is integrated with. Currently supported values are:

  • standalone when running current application without any integration into some other application.
  • express when running current application with Hitchy integrated into an Express-based application.

this.done

This callback is provided by the service Hitchy is integrating with. When using Hitchy with Express invoking this function is starting next handler function registered with Express skipping any code that's authoritative in scope of Hitchy integrating with Express.

Caution

Don't use this function for it might be causing significant side effects.

this.consumed

This property contains markers used internally to handle cases that haven't been handled by any controller. You shouldn't use or adjust those marks.

Request Helpers

In request handlers of controllers and policies there are two provided arguments usually named req and res. The former is basically an IncomingMessage and the latter is a ServerResponse. But either object is extended to provide additional information and functionality.

Standalone vs. Integrated With ExpressJS

Most helpers described here are basically available in a standalone Hitchy application. When using Hitchy integrated with ExpressJS most of these helpers are provided by ExpressJS and thus may behave differently.

In a request handler like

function( req, res ) {
    // TODO add some handling code here
}

the request helpers are available as part of object provided as req.

req.accept

A properly sorted list of MIME type ranges is provided in this property according to any current request's Accept header field. There is always a list of MIME ranges and either item is provided without optional parameters.

Example

When handling request with header Accept: text/*;q=0.5, text/json this property will expose sorted list of given MIME ranges [ "text/json", "text/*" ].

req.cookies

Requires Plugin

This property requires installation of plugin hitchy-plugin-cookies as a dependency of your project.

This property exposes object containing all cookies transmitted by client in current request.

req.fetchBody( parser )

This method promises request's body. The optional parameter can be used to control parser used for extracting contained information.

When integrating with ExpressJS it might have fetched and parsed request body before exposing it as req.body. In this case Hitchy isn't capable of accessing raw request body anymore. This is limiting use of this function.

Supporting this scenario any existing data in req.body will be delivered whenever using this function for fetching request's body without regards to some optionally selected parser.

  • When omitted or set null any parser function in configuration is used to commonly parse raw body for contained information. When there is no configured parser some fallback is used supporting JSON and form-encoded request bodies.

  • On providing function here this one is used to parse the raw body instead of any configured or fallback parser.

  • On providing false the raw body is promised as instance of Buffer. This is bypassing any parser to be invoked thus won't result in caching some parser's output as well.

This method is caching any previously extracted body data in association with provided parser argument. Thus, re-invoking this method with a different parser results in parsing raw body again while providing same parser re-fetches same information as before.

When providing custom function make sure to provide the same instance of that function to benefit from this caching. As an option assign a global body parser function in configuration as config.bodyParser.

req.hitchy 0.2.0+

This property is exposing Hitchy's API.

req.params

This object is populated with named segments of currently dispatched route.

Example

If your handler is bound to handle a route like GET /api/:model/:item and client was requesting /api/user/123 then req.params looks like this:

{
    model: "user",
    item: "123"
}

req.path

This property conveniently provides current request's path which is the requested URL without any appended query string or hash.

Example

On requesting /some/path/name?with=arg this property will provide /some/path/name.

req.query

This property is an object exposing all query parameters.

Example

On requesting /some/path/name?with=arg&another=one this property will provide the following object:

{
    with: "arg",
    another:  "one"
}

req.session

Requires Plugin

This property requires installation of plugin hitchy-plugin-session as a dependency of your project.

This object consists of two properties meant to provide server-side session shared by different requests transmitted from same client.

  • In req.session.user currently authenticated user is stored.

    This feature needs installation of another plugin, e.g. hitchy-plugin-auth.

  • req.session.data can be used in your controllers and policies to store arbitrary information regarding currently requesting client.

    Make sure any stored information can be serialized, thus you shouldn't put instances of some custom class in here, but use native data suitable for converting to/from JSON, only.

Supported Scenarios

Sessions rely on client passing session cookie in every request following some initial one. Usually this is available with browsers requesting pages and assets on behalf of a user. You should not rely on this session feature when it comes to REST APIs, though.

Response Helpers

In handling requests there is a response manager provided in second argument usually named res. Basically this is an instance of ServerResponse. But Hitchy is injecting some additional methods for simplifying generation of responses.

Fluent Interface

Those additional methods listed below are providing fluent interface for chaining multiple invocations.

res.status( 400 ).set( "content-type", "text/json" ).send( { ... } );

However, signatures of methods natively provided as part of ServerResponse aren't adjusted.

Preventing Response on HEAD Requests 0.2.2+

Requests using HTTP method HEAD must not provide a response. Disobeying this usually results in exceptions thrown e.g. on trying to send some JSON-formatted response.

Hitchy is designed to detect any such request limiting capabilities of response manager's methods related to describing some actual content. That's why you don't need to take care of omitting response content in handlers supported HEAD requests as well.

Standalone vs. Integrated With ExpressJS

Most helpers described here are basically available in a standalone Hitchy application. When using Hitchy integrated with ExpressJS most of these helpers are provided by ExpressJS and thus may behave differently.

In a request handler like

function( req, res ) {
    // TODO add some handling code here
}

the response helpers are available as part of object provided as res.

res.format( handlers )

This method provides different handlers for generating response with each handler bound to one particular type or format of response data. According to current request's Accept header the best matching handler is picked to eventually create a response.

A special handler named default is used if neither provided handler is matching any type of response accepted in current request. If this default handler is missing a 406 Not Acceptable is issued implicitly in that case.

Handlers' names are either MIME types or some supported filename extensions considered aliases for related MIME type.

Example

Using this function in a request handler

res.format( {
    html( req, res ) {
        res.send( "<html>...</html>" );
    },
    "text/json"( req, res ) {
        res.json( { some: "data" } );
    },
    default( req, res ) {
        res.status(400).send( "unsupported type of response" );
    }
} )

the response is provided as JSON when requesting with Accept: text/json and as an HTML document when requesting with Accept: text/html.

res.json( data )

This method generates a JSON-formatted response and sends it to the client. It is ending current response implicitly.

Example

res.json( { some: "data" } );

res.redirect( statusCode, url )

Use this helper to instantly generate and send response requesting user to fetch different URL for some desired information.

Example

res.redirect( 301, "https://example.com/" );

res.send( content )

This method is sending provided content to the client implicitly ending response to current request. The response's type of content depends on type of value provided as content here:

  • Providing an object the response is JSON-formatted.

  • When providing a string the response is sent as plain text unless having set some different content-type header before.

  • When providing an instance of Buffer or any other kind of data the response is an octet stream with MIME type application/octet-stream.

Example

res.send( { some: "data" } );
res.send( Buffer.from( "..." ) );

res.set( name, value )

Adjusts single field of response header. Internally this function is invoking res.setHeader().

Example

res.set( "content-type", "text/json;charset=utf8" );
res.set( "x-api-level", "3" );

res.set( fields )

Adjusts multiple fields of response header at once. Internally this function is invoking res.setHeader() for every listed header field.

Example

res.set( {
    "content-type": "text/json;charset=utf8",
    "x-api-level": "3"
} );

res.status( code )

Adjusts HTTP response status code.

Example

res.status( 404 ).json( { error: "no such data" } )

res.type( mime )

Adjusts content-type header field of response supporting several aliases for simplified selection of response type.

Example

res.type( "json" ).send( JSON.stringify( true ) )
res.type( "image/png" ).send( bufferContainingPNG )