Skip to content

Instantly share code, notes, and snippets.

@lomteslie
Created May 2, 2018 21:14
Show Gist options
  • Select an option

  • Save lomteslie/65f26955f5545f301a78a19749ef5b3c to your computer and use it in GitHub Desktop.

Select an option

Save lomteslie/65f26955f5545f301a78a19749ef5b3c to your computer and use it in GitHub Desktop.

Revisions

  1. lomteslie created this gist May 2, 2018.
    91 changes: 91 additions & 0 deletions apiClient.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    import queryString from 'query-string'
    import Immutable from 'seamless-immutable'

    /**
    * API Client
    * Vision-specific client for interacting directly with the API – via these methods.
    *
    * @type {Object}
    */
    const apiClient = {
    get: (...args) => fireRequest('GET', ...args),
    post: (...args) => fireRequest('POST', ...args),
    put: (...args) => fireRequest('PUT', ...args),
    delete: (...args) => fireRequest('DELETE', ...args)
    }

    /**
    * Base API URL that is set in Webpack as a global variable.
    *
    * @type {String}
    */
    const BASE_URL = process.env.API_URL

    /**
    * Fire Request
    * Use the redux-api-middleware to make a request to the API and fire all actions.
    * Success and failure actions are generated accordingly.
    *
    * @param method {String} Restful method.
    * @param uri {String} API URL endpoint.
    * @param data {Object} Any data to send along.
    * @param action {Object} Redux action being triggered.
    * @return {Object} Request config and logic as accepted by the middleware.
    */
    function fireRequest(method, uri = '', data = {}, action) {
    let endpoint = `${BASE_URL}/${uri}`
    let headers = {
    'Content-Type': 'application/json',
    'X-Application-Name': 'Vision'
    }
    let body = null

    // Just in case a falsey value gets through
    if (!data) {
    data = {}
    }

    // Convert immutable data to normal JS
    if (Immutable.isImmutable(data)) {
    data = Immutable.asMutable(data)
    }

    // Assign token to auth header
    if (data.token) {
    headers.Authorization = `Bearer ${data.token}`
    }

    Reflect.deleteProperty(data, 'token')

    // Convert data to query string for GET requests
    if (method === 'GET') {
    endpoint += queryString.stringify(data)
    } else {
    body = JSON.stringify(data)
    }

    const options = {
    method,
    body,
    headers
    }

    return fetch(endpoint, options).then(response => {
    const contentType = response.headers.get('Content-Type')

    if (contentType && ~contentType.indexOf('json')) {
    return response.json().then(jsonResponse => {
    if (response.ok) {
    return Immutable(jsonResponse)
    }

    throw Immutable({
    status: response.status,
    message: jsonResponse.error || 'Looks like something went wrong…'
    })
    })
    }
    })
    }

    export default apiClient