A wrapper around Fetch just for JSON
Why would you fetch anything but json? ;)
fetch-json automatically:
- Converts the HTTP response to JSON if it's not already JSON (especially convenient for HTTP errors)
- Serializes the body payload with
JSON.stringify()
- Adds the
application/json
HTTP header to set the data type - Appends the GET
params
object items to the URL - Runs
.json()
on the response - Sets
credentials
to'same-origin'
(support user sessions in Grails, Rails, PHP, Django, Flask, etc.)
fetch-json is ideal for a JAMstack architecture where "dynamic programming during the request/response cycle is handled by JavaScript, running entirely on the client".
In a web page:
<script src=fetch-json.min.js></script>
or from the jsdelivr.com CDN:
<script src=https://cdn.jsdelivr.net/npm/fetch-json@2.2/dist/fetch-json.min.js></script>
Install package:
$ npm install node-fetch fetch-json
and then import:
const fetchJson = require('fetch-json');
Fetch the NASA Astronomy Picture of the Day:
// NASA APoD
const url = 'https://api.nasa.gov/planetary/apod';
const params = { api_key: 'DEMO_KEY' };
const handleData = (data) =>
console.log('The NASA APoD for today is at: ' + data.url);
fetchJson.get(url, params).then(handleData);
Create a resource for the planet Jupiter:
// Create Jupiter
const resource = { name: 'Jupiter', position: 5 };
const handleData = (data) =>
console.log('Planet:', data); //http response body as an object literal
fetchJson.post('https://httpbin.org/post', resource)
.then(handleData)
.catch(console.error);
For more examples, see the Mocha specification cases:
spec-node.js (Mocha output on Travis CI)
To see a website that incorporates fetch-json, check out DataDashboard:
data-dashboard.js.org 📊
fetch-json calls the native Fetch API if in a web browser and calls node-fetch if running on node.
For comparison, the above POST example in section 2 to create a planet would be done calling the Fetch API directly with the code:
// Create Jupiter (WITHOUT fetch-json)
const resource = { name: 'Jupiter', position: 5 };
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(resource)
};
const handleData = (data) =>
console.log(data); //http response body as an object literal
fetch('https://httpbin.org/post', options)
.then(response => response.json())
.then(handleData)
.catch(console.error);
The example with fetch-json and the example without fetch-json each produce the same output.
The format for using fetch-json is:
fetchJson.get(url, params, options).then(callback);
fetchJson.post(url, resource, options).then(callback);
fetchJson.put(url, resource, options).then(callback);
fetchJson.patch(url, resource, options).then(callback);
fetchJson.delete(url, resource, options).then(callback);
Notes:
- Only the
url
parameter is required. The other parameters are optional. - The
params
object forfetchJson.get()
is converted into a query string and appended to theurl
. - The
resource
object is turned into the body of the HTTP request. - The
options
parameter is passed through to the Fetch API (see theinit
documentation on MDN). options
is enhanced with a boolean setting forstrictErrors
mode (defaultfalse
) that throws an error to.catch()
whenever the HTTP response status is 400 or higher.
If you need to programmatically set the method, use the format:
fetchJson.request(method, url, data, options).then(callback);
Where method
is 'GET'
, 'POST'
, 'PUT'
, 'PATCH'
, or 'DELETE'
, and data
represents
either params
or resource
.
Enable basic logging to the console with:
fetchJson.enableLogger();
To use a custom logger, pass in a function that accepts 9 parameters to log.
To disable logging, pass in false
.
To get an array containing the names of the parameters:
fetchJson.getLogHeaders();
The default console output looks like:
2018-09-12T07:20:12.372Z – "request" - "GET" – "api.nasa.gov" – "https://api.nasa.gov/planetary/apod"
2018-09-12T07:20:13.009Z – "response" - "GET" – "api.nasa.gov" – "https://api.nasa.gov/planetary/apod" - true - 200 - "OK" - "application/json"
The HTTP response body is considered to be JSON if the Content-Type
is "application/json"
or
"text/javascript"
. If the HTTP response body is not JSON, fetch-json passes back
through the promise an object with a bodyText
string field containing response body text.
In addition to the bodyText
field, the object will have the fields: ok
, status
, statusText
,
and contentType
.
For example, an HTTP response for an error status of 500 would be converted to an object similar to:
{
ok: false,
status: 500,
statusText: 'INTERNAL SERVER ERROR',
contentType: 'text/html; charset=utf-8',
bodyText: '<!doctype html><html lang=en><body>Server Error</body></html>'
}
With fetch-json, you know the response body will always be passed back to you as a simple object literal.
To support really old browsers, include polyfills for Promise and Fetch API:
<script src=https://cdn.jsdelivr.net/npm/promise-polyfill@8.1/dist/polyfill.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0/dist/fetch.umd.min.js></script>
Note:
JSDOM does not include fetch
, so you need to add a polyfill.
See usage of whatwg-fetch
in spec/jsdom.js and gulpfile.js.
To be a contributor, fork the project and run the commands npm install
and npm test
on your
local clone. Make your edits and rerun the tests. Pull requests welcome.
Pull requests (PRs) should not update the version
number in package.json or any files in the
dist
folder. The version
number and dist
files are all updated as part of the release
process.
Issues labeled "good first issue" make it easy for first time contributors to participate. Only submit a PR for one of these issues if you're new to this project.
"Stop trying to make fetch happen without #fetchJson!"
Feel free to submit questions at:
github.com/center-key/fetch-json/issues