| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
❤️ Love this project? Support @niftylettuce's FOSS on Patreon or PayPal 🦄
Modern fetch-based alternative to axios/superagent/request. Great for React Native.
New in v2.0.4++: baseURI is now optional and you can pass raw: true as a global or request-based option to get the raw fetch() response (e.g. if you want to use res.arrayBuffer() or any other method manually).
Install the required package:
npm install --save frisbee<script crossorigin="anonymous" src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6,Array.from,Object.getOwnPropertyDescriptors,Object.getOwnPropertySymbols,Promise,Promise.race,Promise.reject,Promise.resolve,Reflect,Symbol.for,Symbol.iterator,Symbol.prototype,Symbol.species,Symbol.toPrimitive,Symbol.toStringTag,Uint8Array"></script>
<script src="https://unpkg.com/frisbee"></script>
<script type="text/javascript">
(function() {
// create a new instance of Frisbee
var api = new Frisbee({
baseURI: 'https://api.startup.com', // optional
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
// this is a simple example using `.then` and `.catch`
api.get('/hello-world').then(console.log).catch(console.error);
//
// see the Usage section below in Frisbee's README for more information
// https://github.com/niftylettuce/frisbee
//
})();
</script>Install the required package:
npm install frisbeeEnsure that your environment is polyfilled with required features (e.g. use @babel/polyfill globally or a service like polyfill.io)
const Frisbee = require('frisbee');
// create a new instance of Frisbee
const api = new Frisbee({
baseURI: 'https://api.startup.com', // optional
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
// this is a simple example using `.then` and `.catch`
api.get('/hello-world').then(console.log).catch(console.error);
// this is a more complex example using async/await and basic auth
(async () => {
// log in to our API with a user/pass
try {
// make the request
let res = await api.post('/v1/login');
// handle HTTP or API errors
if (res.err) throw res.err;
// set basic auth headers for all
// future API requests we make
api.auth(res.body.api_token);
// now let's post a message to our API
res = await api.post('/v1/messages', { body: 'Hello' });
// handle HTTP or API errors
if (res.err) throw res.err;
// now let's get a list of messages filtered by page and limit
res = await api.get('/v1/messages', {
body: {
limit: 10,
page: 2
}
});
// handle HTTP or API errors
if (res.err) throw res.err;
// now let's logout
res = api.post('/v1/logout');
// handle HTTP or API errors
if (res.err) throw res.err;
// unset auth now since we logged out
api.auth();
// for more information on `fetch` headers and
// how to send and expect various types of data:
// <https://github.com/github/fetch>
} catch (err) {
console.error(err);
}
})();const Frisbee = require('frisbee');Frisbee is a function that optionally accepts an argument options, which is an object full of options for constructing your API instance.
Frisbee - accepts an options object, with the following accepted options:
baseURI (String) - the default URI to use as a prefix for all HTTP requests (optional as of v2.0.4+)
If your API server is running on http://localhost:8080, then use that as the value for this option
If you use React Native, then you most likely want to set baseURI as follows (e.g. making use of __DEV__ global variable):
const api = new Frisbee({
baseURI: __DEV__
? process.env.API_BASE_URI || 'http://localhost:8080'
: 'https://api.startup.com'
});You could also set API_BASE_URI as an environment variable, and then set the value of this option to process.env.API_BASE_URI (e.g. API_BASE_URI=http://localhost:8080 node app)
Using React Native? You might want to read this article about automatic IP configuration.
headers (Object) - an object containing default headers to send with every request
body (Object) - an object containing default body payload to send with every request. Either the default body set in options will be used or it will be overridden with a request provided body. Body will not merge nor deep merge.
params (Object) - an object containing default querystring parameters to send with every request (API method specific params options will override or extend properties defined here, but will not deep merge)
logRequest (Function) - a function that accepts two arguments path (String) and opts (Object) and will be called with before a fetch request is made with (e.g. fetch(path, opts) – see Logging and Debugging below for example usage) - this defaults to false so no log request function is called out of the box
logResponse (Function) - a function that accepts three arguments path (String), opts (Object), and response (Object) and has the same parameters as logRequest, with the exception of the third response, which is the raw response object returned from fetch (see Logging and Debugging below for example usage) - this defaults to false so no log response function is called out of the box
auth - will call the auth() function below and set it as a default
parse - options passed to qs.parse method (see qs for all available options)
stringify - options passed to qs.stringify method (see qs for all available options)
addQueryPrefix (Boolean) - defaults to true, and affixes the path with required ? parameter if a querystring is to be passed
format (String) - defaults to RFC1738
arrayFormat (String) - defaults to 'indices'
preventBodyOnMethods (Array) - defaults to [ 'GET', 'HEAD', 'DELETE', 'CONNECT' ], and is an Array of HTTP method names that we will convert a body option to be querystringified URL parameters (e.g. api.get('/v1/users', { search: 'foo' }) will result in GET /v1/users?search=foo). According to RFC 7231, the default methods defined here have no defined semantics for having a payload body, and having one may cause some implementations to reject the request (which is why we set this as a default). If you wish to disable this, you may pass preventBodyOnMethods: false or your own custom Array preventBodyOnMethods: [ ... ]
interceptableMethods (Array) - defaults to all API methods supported below (defaults to GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH)
raw (Boolean) - return a raw fetch response (new as of v2.0.4+)
abortToken (Symbol) - some Symbol that you can use to abort one or more frisbee requests
signal (Object) - an AbortController Signal used to cancel a fetch request
mode (String) - passed to fetch, defaults to "same-origin" (see Fetch's documentation for more info)
cache (String) - passed to fetch, defaults to "default" (see Fetch's documentation for more info)
credentials (String) - passed to fetch, defaults to "same-origin" (see Fetch's documentation for more info)
redirect (String) - passed to fetch, defaults to "follow" (see Fetch's documentation for more info)
referrer (String) - passed to fetch, defaults to "client" (see Fetch's documentation for more info)
Upon being invoked, Frisbee returns an object with the following chainable methods:
api.auth(creds) - helper function that sets BasicAuth headers, and it accepts user and pass arguments
api.setOptions(opts) - helper function to update instance options (note this does not call api.auth internally again even if opts.auth is passed)
api.jwt(token) - helper function that sets a JWT Bearer header. It accepts the jwt_token as a single string argument. If you simply invoke the function null as the argument for your token, it will remove JWT headers.
api.abort(token) - aborts all current/queued requests that were created using token
api.abortAll() - aborts all current/queued - i.e. await-ing in an interceptor - requests
All exposed HTTP methods return a Promise, and they require a path string, and accept an optional options object:
Accepted method arguments:
path required - the path for the HTTP request (e.g. /v1/login, will be prefixed with the value of baseURI if set)
options optional - an object containing options, such as header values, a request body, form data, or a querystring to send along with the request. These options by default are inherited from global options passed to new Frisbee({ options }). For the GET method (and the DELETE method as of version 1.3.0), body data will be encoded in the query string. **This options object is passed to the native Fetch API method, which means you can use native Fetch API method options as well from Fetch's documentation
To make only a certain request be raw and not parsed by Frisbee:
const res = await api.get('/v1/messages', { raw: false });Here are a few examples (you can override/merge your set default headers as well per request):
To turn off caching, pass cache: 'reload' to native fetch options:
const res = await api.get('/v1/messages', { cache: 'reload' });To set a custom header value of X-Reply-To on a POST request:
const res = await api.post('/messages', {
headers: {
'X-Reply-To': '7s9inuna748y4l1azchi'
}
});raw optional - will override a global raw option if set, and if it is true it will return a raw fetch response (new as of v2.0.4+)
List of available HTTP methods:
Note that you can chain the auth method and a HTTP method together:
const res = await api.auth('foo:bar').get('/');interceptor - object that can be used to manipulate request and response interceptors. It has the following methods:
api.interceptor.register(interceptor): Accepts an interceptor object that can have one or more of the following functions
{
request: function (path, options) {
// Read/Modify the path or options
// ...
return [path, options];
},
requestError: function (err) {
// Handle an error occured in the request method
// ...
return Promise.reject(err);
},
response: function (response) {
// Read/Modify the response
// ...
return response;
},
responseError: function (err) {
// Handle error occured in api/response methods
return Promise.reject(err);
}the register method returns an unregister() function so that you can unregister the added interceptor.
api.interceptor.unregister(interceptor): Accepts the interceptor reference that you want to delete.
api.interceptor.clear(): Removes all the added interceptors.
Note that when interceptors are added in the order ONE->TWO->THREE:
We highly recommend to use CabinJS as your Node.js and JavaScript logging utility (see Automatic Request Logging for complete examples).
You can log both requests and/or responses made to fetch internally in Frisbee. Simply pass a logRequest and/or logResponse function.
logRequest accepts two arguments path (String) and opts (Object) and these two arguments are what we call fetch with internally (e.g. fetch(path, opts)):
const cabin = require('cabin');
const frisbee = require('frisbee');
const pino = require('pino')({
customLevels: {
log: 30
},
hooks: {
// <https://github.com/pinojs/pino/blob/master/docs/api.md#logmethod>
logMethod(inputArgs, method) {
return method.call(this, {
// <https://github.com/pinojs/pino/issues/854>
// message: inputArgs[0],
msg: inputArgs[0],
meta: inputArgs[1]
});
}
}
});
const logger = new Cabin({
// (optional: your free API key from https://cabinjs.com)
// key: 'YOUR-CABIN-API-KEY',
axe: { logger: pino }
});
const api = new Frisbee({
logRequest: (path, opts) => {
logger.info('fetch request', { path, opts });
}
});logResponse accepts three arguments, the first two are the same as logRequest (e.g. path and opts), but the third argument is response (Object) and is the raw response object returned from fetch (e.g. const response = await fetch(path, opts)):
const cabin = require('cabin');
const frisbee = require('frisbee');
const pino = require('pino')({
customLevels: {
log: 30
}
});
const logger = new Cabin({
// (optional: your free API key from https://cabinjs.com)
// key: 'YOUR-CABIN-API-KEY',
axe: { logger: pino }
});
const api = new Frisbee({
logResponse: (path, opts, res) => {
logger.info('fetch response', { path, opts, res });
}
});You can run your application with DEBUG=frisbee node app.js to output debug logging statements with Frisbee.
This list is sourced from ESLint output and polyfilled settings through eslint-plugin-compat.
Simply set its value to null, '', or undefined – and it will be unset and removed from the headers sent with your request.
A common use case for this is when you are attempting to use FormData and need the content boundary automatically added.
This is due to a bug with setting the boundary. For more information and temporary workaround if you are affected please see facebook/react-native#7564 (comment).
As of version 1.0.0 we have dropped support for callbacks, it now only supports Promises.
It is a WHATWG browser API specification. You can read more about at the following links:
Yes, a lot of browsers are now supporting it! See this reference for more information http://caniuse.com/#feat=fetch.
Yes you can use the fetch method (polyfill) from whatwg-fetch or node-fetch.
By default, React Native already has a built-in fetch out of the box!
Yes, but you'll need a promise polyfill for older browsers.
Use this package as a universal API wrapper for integrating your API in your client-side or server-side projects.
It's a better working alternative (and with less headaches; at least for me) – for talking to your API – than superagent and the default fetch Network method provide.
Use it for projects in Node, React, Angular, React Native, ...
It supports and is tested for both client-side usage (e.g. with Bower, Browserify, or Webpack, with whatwg-fetch) and also server-side (with node-fetch).
See Background for more information.
See Lad as a great starting point, and read this article about building Node.js API's with authentication.
File an issue on GitHub and we'll try our best help you out.
This package is tested to work with whatwg-fetch and node-fetch.
This means that it is compatible for both client-side and server-side usage.
The docs suggest that you use superagent with React Native, but in our experience it did not work properly, therefore we went with the next best solution, the Github fetch API polyfill included with React Native. After having several issues trying to use fetch and writing our own API wrapper for a project with it (and running into roadblocks along the way) – we decided to publish this.
Here were the issues we discovered/filed related to this:
We know that solutions like superagent exist, but they don't seem to work well with React Native (which was our use case for this package).
In addition, the authors of WHATWG's fetch API only support throwing errors instead of catching them and bubbling them up to the callback/promise (for example, with Frisbee any HTTP or API errors are found in the res.err object).
Therefore we created frisbee to serve as our API glue, and hopefully it'll serve as yours too.
| Name | Website |
|---|---|
| Nick Baugh | http://niftylettuce.com/ |
| Alexis Tyler | |
| Assem-Hafez | |
| Jordan Denison | |
| James | |
| Sampsa Saarela | |
| Julien Moutte | |
| Charles Soetan | |
| Kesha Antonov | |
| Ben Turley | |
| Richard Evans | |
| Hawken Rives | |
| Fernando Montoya | |
| Brent Vatne | |
| Hosmel Quintana | |
| Kyle Kirbatski | |
| Adam Jenkins |
| Back | FazBrowse Home | New Git URL |