Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apollo-fetch

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-fetch - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

5

CHANGELOG.md

@@ -5,2 +5,7 @@ # Change log

### 0.3.0
Changes the middleware and afterware to accept functions instead of objects
`use` and `useAfter` now only accept a single middleware or afterware
### 0.2.0

@@ -7,0 +12,0 @@

41

dist/src/apollo-fetch.js

@@ -27,3 +27,3 @@ "use strict";

if (f) {
f.applyMiddleware.apply(scope, [{ request: request, options: options }, next]);
f.apply(scope, [{ request: request, options: options }, next]);
}

@@ -52,3 +52,3 @@ }

if (f) {
f.applyAfterware.apply(scope, [responseObject, next]);
f.apply(scope, [responseObject, next]);
}

@@ -86,3 +86,2 @@ }

httpError.response = response;
httpError.raw = response.raw;
httpError.parseError = error;

@@ -106,3 +105,3 @@ throw httpError;

parseError = e;
return __assign({}, response, { raw: raw, parsed: null });
return __assign({}, response, { raw: raw });
}

@@ -124,26 +123,20 @@ }); })

}, {
use: function (middlewares) {
middlewares.map(function (middleware) {
if (typeof middleware.applyMiddleware === 'function') {
_middlewares.push(middleware);
}
else {
throw new Error('Middleware must implement the applyMiddleware function');
}
});
use: function (middleware) {
if (typeof middleware === 'function') {
_middlewares.push(middleware);
}
else {
throw new Error('Middleware must be a function');
}
return apolloFetch;
},
useAfter: function (afterwares) {
afterwares.map(function (afterware) {
if (typeof afterware.applyAfterware === 'function') {
_afterwares.push(afterware);
}
else {
throw new Error('Afterware must implement the applyAfterware function');
}
});
useAfter: function (afterware) {
if (typeof afterware === 'function') {
_afterwares.push(afterware);
}
else {
throw new Error('Afterware must be a function');
}
return apolloFetch;
},
_middlewares: _middlewares,
_afterwares: _afterwares,
});

@@ -150,0 +143,0 @@ return apolloFetch;

export interface ApolloFetch {
(operation: GraphQLRequest): Promise<FetchResult>;
use: (middlewares: MiddlewareInterface[]) => ApolloFetch;
useAfter: (afterwares: AfterwareInterface[]) => ApolloFetch;
use: (middlewares: MiddlewareInterface) => ApolloFetch;
useAfter: (afterwares: AfterwareInterface) => ApolloFetch;
}

@@ -10,3 +10,2 @@ export interface GraphQLRequest {

operationName?: string;
context?: object;
}

@@ -17,10 +16,4 @@ export interface FetchResult {

extensions?: any;
context?: object;
}
export interface AfterwareInterface {
applyAfterware(response: ResponseAndOptions, next: Function): any;
}
export interface MiddlewareInterface {
applyMiddleware(request: RequestAndOptions, next: Function): void;
}
export declare type MiddlewareInterface = (request: RequestAndOptions, next: Function) => void;
export interface RequestAndOptions {

@@ -30,2 +23,7 @@ request: GraphQLRequest;

}
export declare type AfterwareInterface = (response: ResponseAndOptions, next: Function) => void;
export interface ResponseAndOptions {
response: ParsedResponse;
options: RequestInit;
}
export interface ParsedResponse extends Response {

@@ -35,6 +33,2 @@ raw: string;

}
export interface ResponseAndOptions {
response: ParsedResponse;
options: RequestInit;
}
export interface FetchOptions {

@@ -44,1 +38,5 @@ uri?: string;

}
export interface FetchError extends Error {
response: ParsedResponse;
parseError?: Error;
}
{
"name": "apollo-fetch",
"version": "0.2.0",
"version": "0.3.0",
"description": "Lightweight implementation of fetch for GraphQL requests",
"author": "Evans Hauser <evanshauser@gmail.com>",
"contributors": [
"Jonas Helfer <jonas@helfer.email>"
"Jonas Helfer <jonas@helfer.email>",
"Sashko Stubailo <sashko@stubailo.com>"
],

@@ -9,0 +10,0 @@ "license": "MIT",

@@ -1,3 +0,4 @@

# apollo-fetch
# apollo-fetch [![npm version](https://badge.fury.io/js/apollo-fetch.svg)](https://badge.fury.io/js/apollo-fetch) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)
`apollo-fetch` is a lightweight client for GraphQL requests that supports middleware and afterware that modify requests and responses.

@@ -7,16 +8,89 @@

# Installation
```
npm install apollo-fetch --save
```
To use `apollo-fetch` in a web browser or mobile app, you'll need a build system capable of loading NPM packages on the client.
Some common choices include Browserify, Webpack, and Meteor +1.3.
# Usage
Simple GraphQL query:
To create a fetch function capable of supporting middleware and afterware, use `createApolloFetch`:
```js
import { createApolloFetch } from 'apollo-fetch'
import { createApolloFetch } from 'apollo-fetch';
const uri = 'http://api.githunt.com/graphql';
const apolloFetch = createApolloFetch({ uri });
```
To execute the fetch function, call `apolloFetch` directly in the following way:
```js
apolloFetch({ query, variables, operationName }) //all apolloFetch arguments are optional
.then(result => {
const { data, error, extensions } = result;
//GraphQL errors and extensions are optional
})
.catch(error => {
//respond to a network error
});
```
Middleware and Afterware are added with `use` and `useAfter` directly to `apolloFetch`:
```js
const apolloFetch = createApolloFetch();
const middleware = ({ request, options }, next) => { ... next(); };
const afterware = ({ response, options }, next) => { ... next(); };
apolloFetch.use(middleware);
apolloFetch.useAfter(afterware);
```
Middleware and Afterware can be chained together in any order:
```js
const apolloFetch = createApolloFetch();
apolloFetch
.use(middleware1)
.use(middleware2)
.useAfter(afterware1)
.useAfter(afterware2)
.use(middleware3);
```
The `apolloFetch` from `apollo-fetch` is an alias for an empty call to `createApolloFetch`
```js
import { apolloFetch } from `apollo-fetch`;
//fetches a query from /graphql
apolloFetch({ query }).then(...).catch(...);
```
For mocking and other fetching behavior, you may pass a fetch into `createApolloFetch`:
```js
const customFetch = createFileFetch();
const apolloFetch = createApolloFetch({ customFetch });
```
# Examples
### Simple GraphQL Query
```js
import { createApolloFetch } from 'apollo-fetch';
const uri = 'http://api.githunt.com/graphql';
const query = `
query sampleQuery(id: ID!) {
sample(id: $id) {
id,
name
query CurrentUser {
currentUser {
login,
}

@@ -27,17 +101,9 @@ }

apolloFetch({ query })
.then( result => {
// GraphQL data, GraphQL errors and GraphQL extensions
const { data, error, extensions } = result;
})
.catch(error => {
//respond to a network error
})
apolloFetch({ query }).then(...).catch(...);
```
Simple GraphQL mutation with authentication middleware.
Middleware has access to the GraphQL query and the options passed to fetch.
### Simple GraphQL Mutation with Variables
```js
import { createApolloFetch } from 'apollo-fetch'
import { createApolloFetch } from 'apollo-fetch';

@@ -47,33 +113,45 @@ const uri = 'http://api.githunt.com/graphql';

const query = `
query sampleMutation(id: ID!) {
addSample(id: $id) {
mutation SubmitRepo ($repoFullName: String!) {
submitRepository (repoFullName: $repoFullName) {
id,
name
score,
}
}
`
`;
const variables = {
repoFullName: 'apollographql/apollo-fetch',
};
const apolloFetch = createApolloFetch({ uri });
apolloFetch.use([{
applyMiddleware: ({ request, options }, next) => {
if (!options.headers) {
options.headers = {}; // Create the headers object if needed.
}
options.headers['authorization'] = 'created token';
apolloFetch({ query, variables }).then(...).catch(...);
```
next();
},
}]);
### Middleware
apolloFetch({ query })
.then(result => {
// GraphQL data, errors, and extensions
const { data, error, extensions } = result;
})
.catch(error => {
//respond to a network error
})
A GraphQL mutation with authentication middleware.
Middleware has access to the GraphQL query and the options passed to fetch.
```js
import { createApolloFetch } from 'apollo-fetch';
const uri = 'http://api.githunt.com/graphql';
const apolloFetch = createApolloFetch({ uri });
apolloFetch.use(({ request, options }, next) => {
if (!options.headers) {
options.headers = {}; // Create the headers object if needed.
}
options.headers['authorization'] = 'created token';
next();
});
apolloFetch(...).then(...).catch(...);
```
### Afterware
Afterware to check the response status and logout on a 401.

@@ -83,3 +161,3 @@ The afterware has access to the raw reponse always and parsed response when the data is proper JSON.

```js
import { createApolloFetch } from 'apollo-fetch'
import { createApolloFetch } from 'apollo-fetch';

@@ -90,39 +168,69 @@ const uri = 'http://api.githunt.com/graphql';

apolloFetch.useAfter([{
applyAfterware: ({ response }, next) => {
if (response.status === 401) {
logout();
}
next();
},
}]);
apolloFetch.useAfter(({ response }, next) => {
if (response.status === 401) {
logout();
}
next();
});
apolloFetch({ query })
.then(result => {
// GraphQL data, errors, and extensions from the server
const { data, error, extensions } = result;
})
.catch(error => {
//respond to a network error
})
apolloFetch(...).then(...).catch(...);
```
Middleware and Afterware can be chained together in any order:
### Error Handling
All responses are passed to the afterware regardless of the http status code.
Network errors, `FetchError`, are thrown after the afterware is run and if no parsed response is received.
This example shows an afterware that can receive a 401 with an unparsable response and return a valid `FetchResult`.
Currently all other status codes that have an uparsable response would throw an error.
This means if a server returns a parsable GraphQL result on a 403 for example, the result would be passed to `then` without error.
Errors in Middleware and Afterware are propagated without modification.
```js
const apolloFetch = createApolloFetch();
apolloFetch.use([exampleWare1])
.use([exampleWare2])
.useAfter([exampleWare3])
.useAfter([exampleWare4])
.use([exampleWare5]);
import { createApolloFetch } from 'apollo-fetch';
const uri = 'http://api.githunt.com/graphql';
const apolloFetch = createApolloFetch({ uri });
apolloFetch.useAfter(({ response }, next) => {
//response.raw will be a non-null string
//response.parsed may be a FetchResult or undefined
if (response.status === 401 && !response.parsed) {
//set parsed response to valid FetchResult
response.parsed = {
data: { user: null },
};
}
next();
});
//Here catch() receives all responses with unparsable data
apolloFetch(...).then(...).catch(...);
```
`apolloFetch` is an alias for an empty call to `createApolloFetch`
### Apollo Integration
`apollo-fetch` is the first part of [Apollo Client's](https://github.com/apollographql/apollo-client) future network stack.
If you would like to try it out today,
you may replace the network interface with the following:
```js
import { apolloFetch } from `apollo-fetch`;
import ApolloClient from 'apollo-client';
import { createApolloFetch } from 'apollo-fetch';
import { print } from 'graphql/language/printer';
//fetches a query from /graphql
apolloFetch({ query }).then(...).catch(...)
const uri = 'http://api.githunt.com/graphql';
const apolloFetch = createApolloFetch({ uri });
const networkInterface = {
request: (req) => apolloFetch({...req, query: print(req.query)})
}
const client = new ApolloClient({
networkInterface,
});
```

@@ -142,3 +250,4 @@

}
/* defaults:
/*
* defaults:
* uri = '/graphql'

@@ -154,8 +263,9 @@ * customFetch = fetch from isomorphic-fetch

(operation: GraphQLRequest): Promise<FetchResult>;
use: (middlewares: MiddlewareInterface[]) => ApolloFetch;
useAfter: (afterwares: AfterwareInterface[]) => ApolloFetch;
use: (middlewares: MiddlewareInterface) => ApolloFetch;
useAfter: (afterwares: AfterwareInterface) => ApolloFetch;
}
```
`GraphQLRequest` is the argument to an `ApolloFetch` call
`GraphQLRequest` is the argument to an `ApolloFetch` call.
`query` is optional to support persistent queries based on only an `operationName`.

@@ -167,3 +277,2 @@ ```js

operationName?: string;
context?: object;
}

@@ -179,3 +288,2 @@ ```

extensions?: any;
context?: object;
}

@@ -187,5 +295,3 @@ ```

```js
MiddlewareInterface {
applyMiddleware(request: RequestAndOptions, next: Function): void;
}
MiddlewareInterface: (request: RequestAndOptions, next: Function) => void

@@ -201,5 +307,3 @@ RequestAndOptions {

```js
AfterwareInterface {
applyAfterware(response: ResponseAndOptions, next: Function): any;
}
AfterwareInterface: (response: ResponseAndOptions, next: Function) => void

@@ -212,3 +316,3 @@ ResponseAndOptions {

`ParsedResponse` adds `raw` (the body from the `.text()` call) to the fetch result, and `parsed` (the parsed JSON from `raw`) to the regular Response from the fetch call.
`ParsedResponse` adds `raw` (the body from the `.text()` call) to the fetch result, and `parsed` (the parsed JSON from `raw`) to the fetch's standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).

@@ -222,3 +326,6 @@ ```js

Errors returned from a call to `ApolloFetch` are normal errors that contain the parsed response, the raw response from .text(), and a possible parse error.
A `FetchError` is returned from a failed call to `ApolloFetch`
is standard [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) that contains the response and a possible parse error.
The `parseError` is generated when the raw response is not valid JSON (when `JSON.parse()` throws) and the Afterware does not add an object to the response's `parsed` property.
Errors in Middleware and Afterware are propagated without modification.

@@ -228,4 +335,4 @@ ```js

response: ParsedResponse;
raw: string;
parseError?: Error;
}
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc