- Notifications
You must be signed in to change notification settings - Fork17
🐶 A wrapper around Fetch just for JSON (with TypeScript declarations)
License
center-key/fetch-json
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A wrapper around Fetch just for JSON
Why would you fetch anything but json? ;)
fetch-json is a lightweight JavaScript library to reduce the boilerplate code needed to makeHTTP calls to JSON endpoints.The minified JS file is under 4 KB.
fetch-json automatically:
- Adds the HTTP header
Content-Type: application/json
to ensure the correct data type - Runs
.json()
on the response - Serializes the body payload with
JSON.stringify()
- Appends
params
to the URL ofGET
requests - Sets
credentials
to'same-origin'
(support user sessions in frameworks like Grails, Rails, PHP, Django, Flask, etc.) - Converts the HTTP text response to JSON if it's not already JSON (convenient for handling HTTP errors)
- Maps HTTP response headers from a
HEAD
request into a simple object
fetch-json is ideal for aJAMstack architecture where "dynamicprogramming during the request/response cycle is handled by JavaScript, running entirely on theclient".
In a web page:
<scriptsrc=fetch-json.min.js></script>
or from thejsdelivr.com CDN:
<scriptsrc=https://cdn.jsdelivr.net/npm/fetch-json@3.3/dist/fetch-json.min.js></script>
Install package for node:
$ npm install fetch-json
and then import:
import{fetchJson}from'fetch-json';
Requires minimumnode v18.
If you use GitHub Actions, ensure the version of node is set correclty:
-uses:actions/setup-node@v3with:node-version:18
Fetch the NASA Astronomy Picture of the Day:
// NASA APoDconsturl='https://api.nasa.gov/planetary/apod';constparams={api_key:'DEMO_KEY'};consthandleData=(data)=>console.log('The NASA APoD for today is at:',data.url);fetchJson.get(url,params).then(handleData);
Example output:
> The NASA APoD for today is at:> https://apod.nasa.gov/apod/image/2107/LRVBPIX3M82Crop1024.jpg
Create a resource for the planet Jupiter:
// Create Jupiterconstresource={name:'Jupiter',position:5};consthandleData=(data)=>console.log('New planet:',data);//http response body as an object literalfetchJson.post('https://centerkey.com/rest/',resource).then(handleData).catch(console.error);
For more examples, see the Mocha specification suite:
spec/node.spec.js(Mocha output for eachbuild underRun npm test
)
To see a website that incorporatesfetch-json, check out DataDashboard:
data-dashboard.js.org 📊
Fetch the NASA Astronomy Picture of the Day:
// NASA APoDconstshow=async()=>{consturl='https://api.nasa.gov/planetary/apod';constparams={api_key:'DEMO_KEY'};constdata=awaitfetchJson.get(url,params);console.log('The NASA APoD for today is at: '+data.url);};show();
Create a resource for the planet Jupiter:
// Create Jupiterconstcreate=async(resource)=>{constdata=awaitfetchJson.post('https://centerkey.com/rest/',resource);console.log('New planet:',data);//http response body as an object literal};create({name:'Jupiter',position:5});
fetch-json calls the nativeFetch API.
For comparison, the POST example in sectionC) Examples to create a planet would bedone calling theFetch APIdirectly with the code:
// Create Jupiter (WITHOUT fetch-json)constresource={name:'Jupiter',position:5};constoptions={method:'POST',headers:{'Content-Type':'application/json','Accept':'application/json',},body:JSON.stringify(resource),};consthandleData=(data)=>console.log(data);//http response body as an object literalfetch('https://centerkey.com/rest/',options).then(response=>response.json()).then(handleData).catch(console.error);
The examplewithfetch-json and the examplewithoutfetch-json each produce the sameoutput.
The format for usingfetch-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);
fetchJson.head(url,params,options).then(callback);//headers returned as an object
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 theFetch 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);
Wheremethod
is'GET'
,'POST'
,'PUT'
,'PATCH'
, or'DELETE'
, anddata
representseitherparams
orresource
.
Turn on basic logging to the console with:
fetchJson.enableLogger();
To use a custom logger, pass in a function that accepts 9 parameters to log.
To get an array containing the names of the parameters:
fetchJson.getLogHeaders();// 'Timestamp', 'HTTP', 'Method', 'Domain', 'URL', 'Ok', 'Status', 'Text', 'Type'
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"
Turn off logging with:
fetchJson.enableLogger();
The HTTP response body is considered to be JSON if theContent-Type
is"application/json"
or"text/javascript"
. If the HTTP response body is not JSON,fetch-json passes backthrough the promise an object with abodyText
string field containing response body text.
In addition to thebodyText
field, the object will have the fields:ok
,status
,statusText
,contentType
, anddata
. If an HTML error response is JSON, thedata
will contain the parsed JSON.
For example, an HTTP response for an error status of 500 would be converted to an objectsimilar 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>',data:null,}
Every response that is not JSON or is an HTTP error will be consistently formatted like the object above. Withfetch-json you know the response will always be passed back to you as a consistent,simple object literal.
UsefetchJson.setBaseOptions()
to configure options to be used on futurefetchJson requests.
The example below sets theAuthorization
HTTP header so it is sent on the subsequent GET andDELETE requests:
fetchJson.setBaseOptions({headers:{Authorization:'Basic WE1MIGlzIGhpZGVvdXM='}});fetchJson.get('https://dna-engine.org/api/books/').then(display);//with auth headerfetchJson.delete('https://dna-engine.org/api/books/3/');//with auth header
To have multiple base options available at the same time, use theFetchJson
class to instantiatemultiple copies offetchJson
:
import{FetchJson}from'fetch-json';constfetchJsonA=newFetchJson({headers:{From:'aaa@example.com'}}).fetchJson;constfetchJsonB=newFetchJson({headers:{From:'bbb@example.com'}}).fetchJson;fetchJsonA.get('https://dna-engine.org/api/books/').then(display);//from aaa@example.comfetchJsonB.delete('https://dna-engine.org/api/books/3/');//from bbb@example.com
See the TypeScript declarations at the top of thefetch-json.ts file.
The declarations provide type information about the API. For example, thefetchJson.post()
function returns aPromise for aFetchResponse
:
fetchJson.post(url:string,resource?:RequestData,options?:FetchOptions):Promise<FetchResponse>
JSDOM does not includefetch
, so you need to add a polyfill.
$ npm install --save-dev whatwg-fetch
See usage ofwhatwg-fetch
inspec/jsdom.spec.js.
Native support forFetch API was introduced innode v18 which became the Active LTS version on 2022-10-25. If you're using an older version ofnode, stick withfetch-json v2.7 and in yourpackage.json file declare a dependency on thenode-fetch polyfill package.
$ npm install node-fetch
Check out therunScriptsConfig
section inpackage.json for aninteresting approach to organizing build tasks.
CLI Build Tools for package.json
- 🎋add-dist-header: Prepend a one-line banner comment (with license notice) to distribution files
- 📄copy-file-util: Copy or rename a file with optional package version number
- 📂copy-folder-util: Recursively copy files from one folder to another folder
- 🪺recursive-exec: Run a command on each file in a folder and its subfolders
- 🔍replacer-util: Find and replace strings or template outputs in text files
- 🔢rev-web-assets: Revision web asset filenames with cache busting content hash fingerprints
- 🚆run-scripts-util: Organize npm package.json scripts into groups of easy to manage commands
- 🚦w3c-html-validator: Check the markup validity of HTML files using the W3C validator
"Stop trying to make fetch happen without#fetchJson!"
Feel free to submit questions at:
github.com/center-key/fetch-json/issues
About
🐶 A wrapper around Fetch just for JSON (with TypeScript declarations)