Hyper Clients

Hyper allows you to configure defaults for your requests as custom Hyper Clients. This is particularly useful for reducing boilerplate in your application.

Defaults are set on the HyperBuilder instance. The easiest way to do this is to configure it in WireBox:

// config/WireBox.cfc
component {

    function configure() {
        map( "StarWarsClient" )
            .to( "hyper.models.HyperBuilder" )
            .asSingleton()
            .initWith(
                baseUrl = "https://swapi.dev/api"
            );
    }

}

Now, you can inject this pre-configured builder wherever you need in your application:

component {

    property name="StarWarsClient" inject="StarWarsClient";

    function findUser( id ) {
        return variables.StarWarsClient.get( "/people/#id#" );
    }

}

You can even create multiple clients using this approach:

// config/WireBox.cfc
component {

    function configure() {
        map( "SWAPIClient" )
            .to( "hyper.models.HyperBuilder" )
            .asSingleton()
            .initWith(
                baseUrl = "https://swapi.dev/api"
            );

        map( "GitHubClient" )
            .to( "hyper.models.HyperBuilder" )
            .asSingleton()
            .initWith(
                baseUrl = "https://api.github.com",
                headers = {
                    "Authorization" = getColdBox().getUtil().getSystemSetting( "GITHUB_TOKEN" )
                }
            );
    }

}

You can also set or change the defaults by either passing the key / value pairs in to the init method or by calling the appropriate HyperRequest method on the HyperBuilder.defaults property.

var hyper = new Hyper.models.HyperBuilder(
    baseUrl = "https://api.github.com"
);
hyper.defaults.withHeaders( { "Authorization" = token } );

The defaults set here need to match the property names on the HyperRequest. These are:

/**
* The httpClient to use for the request
*/
property name="httpClient";

/**
* The baseURL for the request.
* e.g. https://api.github.com/
*/
property name="baseUrl" default="";

/**
* The URL for the request.
* It can either be a full url
* or a URI resource for use with the baseURL.
* e.g. /repos
*/
property name="url" default="";

/**
* Setting this to true will change all relative urls in the document to absolute.
*/
property name="resolveUrls" default="false";

/**
* Setting this to false will not automatically encode the url passed.
* WARNING: Setting this to false is not supported on Adobe engines.
*/
property name="encodeUrl" default="true";

/**
* The HTTP method for the request.
*/
property name="method" default="GET";

/**
* The username for the request for basic auth.
*/
property name="username" default="";

/**
* The password for the request for basic auth.
*/
property name="password" default="";

/**
* Timeout, in seconds, for the request.
*/
property name="timeout" default="10";

/**
* The maximum number of redirects to follow.
* A value of `*` will follow redirects infinitely.
*/
property name="maximumRedirects" default="*";

/**
* The body to send with the request.
* How the body is serialized is
* determined by the bodyFormat.
*/
property name="body" default="";

/**
* The format to serialize the body.
* e.g. `json` or `formFields`
*/
property name="bodyFormat" default="json";

/**
* The referring response in the case of redirects.
*/
property name="referrer";

/**
* A struct of headers for the request.
*/
property name="headers";

/**
* A struct of query parameters for the request.
*/
property name="queryParams";

/**
* Flag to throw on a cfhttp error.
*/
property name="throwOnError" default="false";

/**
* The full path to a PKCS12 format file that contains the client certificate for the request.
*/
property name="clientCert";

/**
* 	Password used to decrypt the client certificate.
*/
property name="clientCertPassword";

/**
* The domain for the request for NTLM auth.
*/
property name="domain" default="";

/**
* The workstation for the request for NTLM auth.
*/
property name="workstation" default="";

/**
* The authType for the request
*/
property name="authType" default="BASIC";

/**
* An array of callback functions to call
* before firing off a request.
*/
property name="requestCallbacks" type="array";

/**
* An array of callback functions to call
* after receiving a response.
*/
property name="responseCallbacks" type="array";

If you need per-request or per-response manipulation of defaults, use the requestCallbacks and responseCallbacks hooks.

map( "ApiClient" )
    .to( "hyper.models.HyperBuilder" )
    .asSingleton()
    .initWith(
        baseUrl = getColdBox().getUtil().getSystemSetting( "API_URL" ),
        requestCallbacks = [
            // provide the current user's token for the request
            function( req ) {
                var auth = getWireBox().getInstance( "AuthenticationService@cbauth" );
                req.withHeaders( "Authorization", auth.user().getApiToken() );
            }
        ],
        responseCallbacks = [
            // map custom `error` property to an exception
            function ( res ) {
                if ( !res.isError() ) {
                    return;
                }
                
                var body = res.json();
                throw(
                    type = "ApiError",
                    message = body.error.message,
                    detail = body.error.code
                );
            }
        ]
    );

Last updated