Coder Social home page Coder Social logo

ladjs / frisbee Goto Github PK

View Code? Open in Web Editor NEW
1.1K 22.0 70.0 1.63 MB

:dog2: Modern fetch-based alternative to axios/superagent/request. Great for React Native.

Home Page: https://niftylettuce.com/frisbee

License: MIT License

JavaScript 97.72% HTML 2.28%
api-wrapper superagent frisbee fetch fetch-api whatwg whatwg-fetch xhr request file-upload

frisbee's Introduction

Frisbee

Slack Status npm version npm downloads build status code coverage code style styled with prettier made with lass license

โค๏ธ 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).

Table of Contents

Install

Node (Koa, Express, React Native, ...)

  1. Install the required package:

    npm install --save frisbee
  2. See usage example and API below

Browser

VanillaJS

  1. Load the package via <script> tag (note you will need to polyfill with required features):
<script crossorigin="anonymous" src="https://polyfill.io/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>
  1. See usage example and API below for a more complete example.

Bundler

  1. Install the required package:

    npm install frisbee
  2. Ensure that your environment is polyfilled with required features (e.g. use @babel/polyfill globally or a service like polyfill.io)

  3. See usage example and API below

Usage

Example

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);
  }
})();

API

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

      • Tip: You'll most likely want to set the "Accept" header to "application/json" and the "Content-Type" header to "application/json"
    • 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)

      • ignoreQueryPrefix (Boolean) - defaults to true, and parses querystrings from URL's properly
    • 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

    • You can pass creds user and pass as an array, arguments, or string: ([user, pass]), (user, pass), or ("user:pass"), so you shouldn't have any problems!
    • If you don't pass both user and pass arguments, then it removes any previously set BasicAuth headers from prior auth() calls
    • If you pass only a user, then it will set pass to an empty string '')
    • If you pass : then it will assume you are trying to set BasicAuth headers using your own user:pass string
    • If you pass more than two keys, then it will throw an error (since BasicAuth only consists of user and pass anyways)
  • 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:

      • api.get(path, options) - GET
      • api.head(path, options) - HEAD (does not currently work - see tests)
      • api.post(path, options) - POST
      • api.put(path, options) - PUT
      • api.del(path, options) - DELETE
      • api.delete(path, options) - DELETE
      • api.options(path, options) - OPTIONS (does not currently work - see tests)
      • api.patch(path, options) - PATCH
    • 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:

      • The request/requestError functions will run in the same order ONE->TWO->THREE.
      • The response/responseError functions will run in reversed order THREE->TWO->ONE.

Logging and Debugging

We highly recommend to use CabinJS as your Node.js and JavaScript logging utility (see Automatic Request Logging for complete examples).

Logging Requests and Responses

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 });
  }
});

Debug Statements

You can run your application with DEBUG=frisbee node app.js to output debug logging statements with Frisbee.

Common Issues

Required Features

This list is sourced from ESLint output and polyfilled settings through eslint-plugin-compat.

  • Array.from() is not supported in IE 11
  • Object.getOwnPropertyDescriptors() is not supported in IE 11
  • Object.getOwnPropertySymbols() is not supported in IE 11
  • Promise is not supported in Opera Mini all, IE Mobile 11, IE 11
  • Promise.race() is not supported in Opera Mini all, IE Mobile 11, IE 11
  • Promise.reject() is not supported in Opera Mini all, IE Mobile 11, IE 11
  • Promise.resolve() is not supported in Opera Mini all, IE Mobile 11, IE 11
  • Reflect is not supported in IE 11
  • Symbol.for() is not supported in IE 11
  • Symbol.iterator() is not supported in IE 11
  • Symbol.prototype() is not supported in IE 11
  • Symbol.species() is not supported in IE 11
  • Symbol.toPrimitive() is not supported in IE 11
  • Symbol.toStringTag() is not supported in IE 11
  • Uint8Array is not supported in IE Mobile 11

Frequently Asked Questions

How do I unset a default header

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.

Why do my form uploads randomly fail with React Native

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).

Does this support callbacks, promises, or both

As of version 1.0.0 we have dropped support for callbacks, it now only supports Promises.

What is the fetch method

It is a WHATWG browser API specification. You can read more about at the following links:

Does the Browser or Node.js support fetch yet

Yes, a lot of browsers are now supporting it! See this reference for more information http://caniuse.com/#feat=fetch.

If my engine does not support fetch yet, is there a polyfill

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!

Can I make fetch support older browsers

Yes, but you'll need a promise polyfill for older browsers.

What is this project about

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).

Why not just use superagent or fetch

See Background for more information.

Want to build an API back-end with Node.js

See Lad as a great starting point, and read this article about building Node.js API's with authentication.

Need help or want to request a feature

File an issue on GitHub and we'll try our best help you out.

Tests

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.

Development

  1. Fork/clone this repository
  2. Run npm install
  3. Run npm run watch to watch the src directory for changes
  4. Make changes in src directory
  5. Write unit tests in /test/ if you add more stuff
  6. Run npm test when you're done
  7. Submit a pull request

Background

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.

Contributors

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

Credits

License

MIT ยฉ Nick Baugh

frisbee's People

Contributors

acecode avatar akmjenkins avatar almouro avatar aretecode avatar assem-hafez avatar bradjones1 avatar brentvatne avatar casoetan avatar davidgovea avatar hawkrives avatar hosmelq avatar jmoutte avatar jordandenison avatar kesha-antonov avatar kkirby avatar montogeek avatar niftylettuce avatar omgimalexis avatar rmevans9 avatar sampsasaarela avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frisbee's Issues

res.body return a ReadableByteStream object on Chrome

Hi,

I am using the latest verison of Chrome on OS X (Version 50.0.2661.102 (64-bit)), with Frisbee, and response.body will return ReadableByteStream instead of an expected response object as built by the result of parsing a json response.

This seems to be the standard, but then why would the frisbee doc give this example? Trying to read the response with response.json() will return the following error: Uncaught (in promise) TypeError: Already read.

Custom error types

It would be nice for downstream error handling if frisbee had custom error types like FrisbeeRequestError, or even allowed for specifying error types in config.

Android Cookies are not persisted across network requests

Hi,

When I am calling get its returning session expired. API is not getting cookie value along with get request. I can see the set-Cookie value in initial login(post) request. But its not using for next API calls. This is happening only in Android. iOS is working perfectly fine.

Any Idea what I am missing here.

Missing babel-runtime?

Is there something I'm missing after upgrading to 1.0.5 with the new "import" syntax? Continually getting this error now:

Unable to resolve module babel-runtime/regenerator from /Users/Mac/Desktop/Mobile/node_modules/frisbee/lib/frisbee.js: Unable to find this module in its module map or any of the node_modules directories under /Users/node_modules/babel-runtime/regenerator and its parent directories

Help!

Add querystring

Hi guys, can someone explain me how to add a querystring to my request? Reading the documentation it says I can do it but I haven't found the way to do it.

Imagine my baseURI is: https://mybaseuri.com/
My service is: users
And I want to add: userId=0209206245902063

So it should look like https://mybaseuri.com/users?userId=0209206245902063

An example would be really appreciated. Thanks in advance.

Helpful error messages when the request fails

Is there a way that some helpful error messages can be thrown rather than just 'Network request failed' because that does not really tell anything about the failure. Any help will be appreciated.

Error / stack trace whenever API returns non-ok response

I'm using frisbee in an expo project, consuming a Python (Flask-Classful) API. Whenever my API returns a non-ok response, I get a stack trace as follows:

Stack trace:
  node_modules/frisbee/lib/index.js:184:40 in _callee$
  node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
  node_modules/regenerator-runtime/runtime.js:288:30 in invoke
  node_modules/frisbee/lib/index.js:7:103 in asyncGeneratorStep
  node_modules/frisbee/lib/index.js:9:212 in _next
  node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
  node_modules/promise/setimmediate/core.js:123:25 in <unknown>
  node_modules/react-native/Libraries/Core/Timers/JSTimers.js:152:14 in _callTimer
  node_modules/react-native/Libraries/Core/Timers/JSTimers.js:200:17 in _callImmediatesPass
  node_modules/react-native/Libraries/Core/Timers/JSTimers.js:464:30 in callImmediates
  node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:320:6 in __callImmediates
  node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:135:6 in <unknown>
  node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:297:10 in __guard
  node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:134:17 in flushedQueue
  ...

It's kind of difficult for me to debug, because my local node_modules/frisbee/lib/index.js is so different to the code in git, I believe due to regenerator. I'd be happy to learn how to debug this more smartly. I've read about babel and regenerator but as a newbie to this ecosystem it's a bit rough. I don't know if the issue is in frisbee or regenerator, and I don't understand why frisbee uses regenerator at all, as I don't see any function* in the code.

However, by judicious use of console.log, I understand that the problem occurs in case 27: in the transpiled code:

                  case 27:
                    resolve(res);
                    return _context.abrupt("return");

I believe that the original code is at https://github.com/niftylettuce/frisbee/blob/master/src/index.js#L210 (end of the if (!res.ok) block.

I hope this is enough information to understand what the issue is, but if not, I'm happy to provide more, just let me know what you need. I'm using Expo 32 and node 10.15.2.

React Native: Android vs iOS JSON parsing

Started working on polishing the Android version of our React Native application, and I came across a strange issue that I'm not sure how to solve.

I was not able to login to the application once I got it building. So, I did some debugging with log statements and found that the session token and other information from the login api call was not being saved properly. Doing console.log(response.body) showed all the information I expected, but doing console.log(response.body.session_token) gave undefined. On a hunch, I tried passing the body into JSON.parse and found that I was able to get the session token and other data just fine.

Going back to iOS however throws an error on the JSON.parse line, because response.body is already an object and not a string.

Is there something going on here between the operating systems? Looking at the frisbee source shows that it should be calling JSON.parse on my behalf, so I am very confused at the discrepancy here. I'd rather not pepper the code with try catches to parse the response properly on both platforms.

Body handling for get and delete methods

Currently Frisbee converts body into a query string for get and delete methods. That's weird because it's an artificial limitation and there is no way to workaround it. On the other hand it requires additional tooling to add a query string to an url.

I propose to bring get and delete methods in line with the rest of methods and introduce a params option, that will stringify params and add it to url. I would be happy to send PRs!

Estrange parseErr

When I test this:

const client = new Frisbee({baseURI: 'http://localhost:3000'});
console.log(client);   

I've got this:

  console.log src\sync\tests\sync-http-client.test.js:13
    Frisbee {
      opts: { baseURI: 'http://localhost:3000' },
      parseErr:
       Error: Invalid JSON received from http://localhost:3000

I haven't done any requests before calling that code, so I must assume this is some kind of bug?

Embed https://www.npmjs.com/package/urlsearchparams directly in package

So we can do stuff like this without needing querystring modules.

 let params = new URLSearchParams();
        params.append('key', 'foobar');
        params.append('language', 'en');
        params.append('location', [
          coords.latitude,
          coords.longitude
        ].join(','));
        params.append('radius', 500);
        googleapi.get(
          '/maps/api/place/nearbysearch/json',
          { body: params },
          (err, res, message) => {
            console.log('googleapi', 'err', err,
                        'res', res, 'message', message);
          }
        );

http methods not available in jest tests

Hi, I'm trying to test my application with jest and noticed, that I don't have the http methods on my Frisbee instance.
Scenario:

import Frisbee from 'frisbee';
// ...
const api = new Frisbee('http://example.com');
api.get // undefined

Result: api.get is undefined

When I link frisbee locally with yarn link and import the src:

import Frisbee from 'frisbee/src';
// ...
const api = new Frisbee('http://example.com');
api.get // function(...) {...}

Result: api.get is defined

Could not find out why. The code in frisbee/dist/index.js seems to implement these methods ๐Ÿคทโ€โ™‚๏ธ

Thanks for ur help ๐Ÿ™

Authorization header should be customizable

@niftylettuce when after login there is a token key dispatched from the server and it should be saved in the device.
Can I use auth('123123123ggg') as the one string for future? Can i expect to see the header contains
Authorization: 123123123ggg as the authorised token? Is it a way to store this piece of string into frisbee for future header use?

Incorrectly describes Fetch as part of ES

This says in several places (in the README, on npm) that fetch is part of ECMAScript (6, or 7) but that's not correct. It's defined by a WHATWG spec. This in particular doesn't make sense:

Why don't you have an ES5 compiled version readily available in this git repo?
As this module relies on ES6 fetch, there is currently no backwards compatibility for ES5

  • Availability of fetch has little to do with ES version support, except for Promise, which can be polyfilled in ES5.
  • The expectation would likely be for an ES5 version on npm, not in the source repo.

Debug logging

How do you log request / response for debugging purposes with Frisbee?

Incorrect project description

The project description reads:

Stripe-inspired API wrapper around ES6/ES7's fetch() method

but fetch is a WHATWG browser API spec, not an ES6/7 feature.

Optional baseURI

I was very enthusiastic about this package but had to switch back to Axios after figuring out that Frisbee is unable to do requests that are relative to current domain like api.get('/api/endpoint').

Host environment variable isn't always available or practical. I would suggest to make it optional, as it is in every other library around. If mandatory baseURI is there to address native platforms, this could be handled by platform detection.

babel-runtime seems to be deprecated

It seems that babel-runtime is an undocumented package, the official babel documentation, suggest using either babel-polyfill (not a good idea for a lib) or Facebook's regenerator-runtime/runtime

On a higher level, I think Frisbee should not be using async/await and probably should stick to simple Promises. async/await are Promises behind the hood, and make it harder to reason about asynchronous execution flows, and you still end up having to interact with Promises for things such as Promise.all.

async/await were introduced to help expand Javascript to more programmers who are familiar with imperative programming and have a hard time breaking down nested calls, but generally should not be used by a library, especially when it introduces a runtime dependency.

Network Request Failed

Hello! I am trying to set up a phone verification using https://github.com/joinspontaneous/react-native-phone-verification

I am currently only using their example code, given here: https://github.com/joinspontaneous/react-native-phone-verification/blob/master/example/index.ios.js

However, I get this result when trying to run their code:
simulator screen shot - iphone 8 - 2018-07-02 at 13 21 34

Of course I have tried with my actual phone number, same result. I don't know how to approach this issue, and I am fairly new with React Native. Any help appreciated! Thanks! - Ralfi

XML response support

Looking briefly through the docs, I wasn't able to find support for XML responses from a server (e.g. response of type Document to allow for XML dom parsing). Did I miss something? Any advice on a set up to deal with both XML and JSON responses from a server?

Body parameters are empty in POST

Whenever making a POST request, the variables passed in body are empty. When passing the following to a POST endpoint, the result is {}

      const res = await api.post('/test', {
          body: {"test" : "test"}
        });

It works perfectly well with GET requests to GET endpoints.

Abort() function

Is abort() or similar function available? Fetch is known to not have abort() in place. I am considering to use frisbee in React Native but am thinking to cancel the connections when component unmounts. Or, could it be that, for fetch-based libraries, it is not necessary to have abort() function in place?

Logger hook

Would be great to add some optional request logging with something like:

new Frisbee({
  logger: myLogger
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.