Options
All
  • Public
  • Public/Protected
  • All
Menu

Contains the minimum functionality necessary to convert a DataDefinition object into a Request and to execute that Request against an Adapter, returning a Response with the requested data.

Hierarchy

  • DataLayer

Index

Methods

  • Converts a DataDefinition object into a Request object that can be passed to fetch. The proxy passed to createDataLayer will be used to fill out the Request using any configured ProxyRules.

    Keeping your data definition objects separate from request objects enables us to construct dynamic requests based on ProxyRules set at runtime. This means we can change the endpoints and protocols using configuration data rather than code.

    throws

    A valid DataDefinition object must be passed to createRequest.

    example
    // save modified user data using a PATCH

    import { createPatch } from 'some/json-patch/library';
    import { createRequest, fetch } from '~/path/to/datalayer';

    const operation = {
    base: 'my-app',
    method: 'PATCH',
    path: '/users/:id'
    };

    export async function saveUserData(id, modified, original) {
    const params = { id };
    const body = createPatch(original, modified);
    const request = createRequest(operation, params, body);
    const response = await fetch(request).catch(errors.rethrow(errors.fatal(params)));
    return response.data;
    }
    example
    // load data using the current domain and protocol

    import { createRequest, fetch } from '~/path/to/datalayer';

    const operation = {
    method: 'GET',
    // by not specifying a `base` value the resulting
    // URL will be relative to the current domain and
    // protocol
    path: '/users/:id'
    };

    export async function loadUserData(id) {
    const params = { id };
    const request = createRequest(operation, params);
    const response = await fetch(request).catch(errors.rethrow(params));
    return response.data;
    }

    Parameters

    • definition: DataDefinition

      The DataDefinition to convert into a Request using ProxyRules.

    • Optional params: Record<string, any>

      Optional parameters used to tokenize the URL or to append to the QueryString.

    • Optional body: any

      Optional data to send with the request.

    Returns Request

    A fully formed Request that can be passed to fetch.

  • Converts a Request into a Response by running the request through an appropriate Adapter.

    throws

    Adapter not found.

    throws

    Invalid request passed to fetch.

    throws

    (if the Response.status is not 2xx)

    example
    import xhr from '@paychex/adapter-xhr';
    import tracker from '~/path/to/tracker';
    import proxy from '~/path/to/proxy';

    // NOTE: you will probably already have access to
    // a datalayer and not need to create one yourself
    const { fetch, createRequest } = data.createDataLayer(proxy, xhr);

    const request = createRequest({
    base: 'my-app',
    path: '/live',
    });

    fetch(request)
    .then(response => {
    tracker.event('app is live', {
    status: response.status,
    message: response.statusText,
    moreInfo: response.data,
    });
    })
    .catch(tracker.error);

    Parameters

    Returns DataPromise

    Information about the data operation.

  • setAdapter(name: string, adapter: Adapter): void
  • Registers an Adapter with the given name. The fetch method will match the 'adapter' value on the Request it is given with any Adapters registered here.

    NOTE: The default adapter for a Request is the adapter used to construct the data layer, which is always registered as 'default'.

    example
    // create a custom Adapter that uses the
    // popular Axios library to make data calls
    // https://github.com/axios/axios

    import axios from 'axios';
    import { cloneDeep } from 'lodash';
    import { setAdapter, createRequest, fetch } from '~/path/to/datalayer';

    const http = axios.create({
    withCredentials: true,
    headers: { accept: 'application/json' }
    });

    // construct and return a Response object
    // using the values provided by Axios
    function createResponseFromSuccess(axiosResponse) { ... }
    function createResponseFromFailure(axiosError) { ... }

    setAdapter('axios', function useAxios(request) {
    // convert the Request into a config
    // that Axios understands -- e.g. axios
    // uses request.data instead of request.body
    const config = cloneDeep(request);
    config.data = request.body;
    return axios(config)
    // always resolve with a Response,
    // regardless of any errors:
    .then(createResponseFromSuccess)
    .catch(createResponseFromFailure);
    });

    // usage:
    const definition = {
    base: 'my-app',
    path: '/path/to/data',
    adapter: 'axios', // <-- use our custom adapter
    method: 'POST',
    };

    export async function saveData(data) {
    // our code looks the same regardless of which adapter
    // is used to make the data call; the adapter could even
    // be changed dynamically by the rules in our Proxy
    const request = createRequest(definition, null, data);
    const response = await fetch(request);
    return response.meta.headers['e-tag'];
    }

    Parameters

    • name: string

      The name of the Adapter to register.

    • adapter: Adapter

      The Adapter to register.

    Returns void