Skip to content

Instantly share code, notes, and snippets.

@lomteslie
Created May 2, 2018 21:14
Show Gist options
  • Save lomteslie/65f26955f5545f301a78a19749ef5b3c to your computer and use it in GitHub Desktop.
Save lomteslie/65f26955f5545f301a78a19749ef5b3c to your computer and use it in GitHub Desktop.
apiClient.js
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment