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