FetchParse.js
!NPM versionnpm-badge
!Build statustravis-badgeFetchParse.js is a mixin for the Fetch APIfetch for browsers and Node.js that automatically buffers response bodies and assigns them as
body
on the response object (saving you from extra res.text()
or res.json()
calls). It can also optionally parse response bodies based on the Content-Type
header (using MediumType.jsmedium-type for media types).Installing
npm install fetch-parse
FetchParse.js follows semantic versioning, so feel free to depend on its major version with something like
>= 1.0.0 < 2
(a.k.a ^1.0.0
).Using
Pass the nativefetch
function to fetchParse
to get back a new fetch
function that will buffer all responses and assign the buffered response body to the body
property on the response object. It'll also parse JSON responses (those whose Content-Type
matches application/json
or */*+json
):var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(fetch)
The above is equal to calling
fetchParse
with the wildcard media type:var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(fetch, {"*/*": true})
Now, calling
apiFetch
will give you back a Promise
with a regular Response
object, but with the body
property assigned to the buffered response body:apiFetch("/users").then(function(res) {
// If Content-Type of /users was application/json and it returned
// an array, you could start using it right there:
res.body[0].email
})
For built-in parsers that FetchParse.json includes, see below.
Parsers
To configure what media types FetchParse.js buffers and parses, pass an object of media type patterns andtrue
s. The true
value there indicates you'd like to use the default parser. If you need a custom parser, see Custom Parsers.var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(fetch, {
"text/markdown": true,
"json": true,
})
FetchParse.js uses MediumType.jsmedium-type's
MediumType.prototype.match
to match the parser pattern against the response's Content-Type
header. The buffering and parsing behavior is dependent on Content-Type
because that allows enabling default parsing of every response with {"*/*": true}
, but still get text/plain
parsed as a string, application/json
as a JavaScript object etc.Default Parsers
Content-Type
| Description
-------------------|------------
text/*
| Calls res.text()
and returns a string.
application/json
| Equivalent to res.json()
and returns a parsed object.
*/*+json
| See application/json
above.
application/xml
| Calls res.text()
and returns a string.
*/*+xml
| See application/xml
above.
*/*
| Calls res.arrayBuffer()
and returns an ArrayBuffer
.Shorthands
Aside from regular media type patterns, FetchParse.js has two shorthands for JSON and XML. That's because RFC 6839rfc6839 specifies standardized suffices for those two in addition toapplication/json
and application/xml
. Using json
for example saves you from having to specify both patterns explicitly.Shorthand | Types ----------|------
json
| application/json
, */*+json
xml
| application/xml
, */*+xml
Custom Parsers
To use a custom parser for some media types, pass an object mapping a media type pattern to that parse function. The parse function must take aFetch.Request
object and return a Promise
of a body. FetchParse.js will itself assign that to the body
property on the response object.var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(fetch, {
"text/html": parseHtml,
"image/*": parseImage,
"application/vnd.example.model+json": parseModel
})
You can implement
parseHtml
by first calling Response.prototype.text
to get the plain-text version and then creating a DocumentFragment
from it:function parseHtml(res) {
return res.text().then(function(html) {
return document.createRange().createContextualFragment(html)
})
}
For converting bytes of an image to a URL you could later use with
<img src="" />
, you could call Response.prototype.arrayBuffer
and create a Blob URL from it (e.g. blob:d3958f5c-0777-0845-9dcf-2cb28783acaf
):function parseImage(res) {
return res.arrayBuffer().then(function(body) {
var blob = new Blob([body], {type: res.headers.get("content-type")})
return URL.createObjectURL(blob)
})
}
To parse JSON into a your own model instance, you can first use
Response.prototype.json
to have it parsed into an object and then instantiate your model with it:function Model(attrs) { this.attributes = attrs }
function parseModel(res) {
return res.json().then(function(attrs) { return new Model(attrs) })
}
Browser
Browsers have the Fetch API available atwindow.fetch
:var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(window.fetch)
Node.js
Node.js doesn't have a built-in implementation of the Fetch API, but you can use any library with a compatible interface, such as my Fetch/Off.jsfetch-off or node-fetchnode-fetch:var fetch = require("fetch-off")
var fetchParse = require("fetch-parse")
var apiFetch = fetchParse(fetch, "https://example.com")
License
FetchParse.js is released under a Lesser GNU Affero General Public License, which in summary means:- You can use this program for no cost.
- You can use this program for both personal and commercial reasons.
- You do not have to share your own program's code which uses this program.
- You have to share modifications (e.g. bug-fixes) you've made to this program.
For more convoluted language, see the
LICENSE
file.About
Andri Möllmoll typed this and the code.Monday Calendarmonday supported the engineering work.
If you find FetchParse.js needs improving, please don't hesitate to type to me now at andri@dot.eeemail or create an issue onlineissues.