Define an API
module, that does the actual AJAX requests:
const API = {
/** Simple service for generating different HTTP codes. */
url: 'http://httpstat.us/',
/**
* fetch() will only reject a promise if the user is offline,
* or some unlikely networking error occurs, such a DNS lookup failure.
* However, there is a simple `ok` flag that indicates
* whether an HTTP response’s status code is in the successful range or not.
*/
_handleError(_response) {
return _response.ok ? _response : Promise.reject(_response.statusText);
},
get(_endpoint) {
return window.fetch(this.url + _endpoint, {
method: 'GET',
headers: new Headers({
'Accept': 'application/json'
})
})
.then(this._handleError)
.catch( error => { throw new Error(error) })
},
post(_endpoint, _body) {
return window.fetch(this.url + _endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: _body
})
.then(this._handleError)
.catch( error => { throw new Error(error) })
}
};
Why this is good:
- Fetch API is not tightly coupled with our code. We can alter the implementation and implement jQuery
$.ajax()
or zlFetch instead only by tweaking the API module. As long as we return a Promise - the implementation in all other modules stays the same.
Define Object that handles the data (Repository-ish pattern):
import API from './api.js'; // Import it into your code however you like
const WeatherRepository() {
_normalizeData(currentWeather) {
// Take only what our app needs and nothing more.
const { t, w, p } = currentWeather;
return {
temperature: t,
windspeed: w,
pressure: p
};
},
/**
* Get current weather.
* @return {Promise}
*/
get(){
return API.get('/weather')
.then(this._normalizeData);
}
}
Why this is good:
- Throughout our codebase via
WeatherRepository.get()
we access meaningful and semantic attributes like.temperature
and.windspeed
instead oft
ands
. - Via the
_normalizeData()
we expose only parameters we need and we simply don't include (hide) all others. - If the response attributes names change (or we need to wire-up another API with different response structure), we only need to tweak
_normalizeData()
. - If we want to implement a caching mechanism, as long as
WeatherRepository.get()
returns a Promise, we don’t need to change the implementation in any other module.