Skip to content

Commit

Permalink
feat: add beforeFetch option to `RelayNetworkLayer(middlewares, { b…
Browse files Browse the repository at this point in the history
…eforeFetch })`.

BREAKING CHANGE: If you use subscriptions in your app and provide
`subscribeFn` as a second argument for RelayNetworkLayer. Now you should
to provide it as a named option: ```new RelayNetworkLayer(middlewares, {
subscribeFn: ...fn.code... });`.
  • Loading branch information
nodkz committed Mar 3, 2018
1 parent 5a5c3f5 commit c4b6f2c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ with various middlewares which can manipulate requests/responses on the fly (cha

Network Layer for Relay Classic can be found [here](https://github.com/nodkz/react-relay-network-layer).

Migration guide from v1 to v2 can be found [here](https://github.com/nodkz/react-relay-network-modern/releases/tag/v2.0.0).

`ReactRelayNetworkModern` can be used in browser, react-native or node server for rendering. Under the hood this module uses global `fetch` method. So if your client is too old, please import explicitly proper polyfill to your code (eg. `whatwg-fetch`, `node-fetch` or `fetch-everywhere`).

Install
Expand Down Expand Up @@ -166,13 +168,24 @@ const network = new RelayNetworkLayer([

return res;
}
]); // as second arg you may pass SubscribeFunction
], opts); // as second arg you may pass advanced options for RRNL

const source = new RecordSource();
const store = new Store(source);
const environment = new Environment({ network, store });
```

### Advanced options (2nd argument after middlewares)
RelayNetworkLayer may accept additional options:
```js
const middlewares = []; // array of middlewares
const options = {}; // optional advanced options
const network = new RelayNetworkLayer(middlewares, options);
```
Available options:
- **subscribeFn** - if you use subscriptions in your app, you may provide this function which will be passed to [RelayNetwork](https://github.com/facebook/relay/blob/master/packages/relay-runtime/network/RelayNetwork.js).
- **beforeFetch** - if you need synchronously render app on the client side from already generated payload by server (SSR) this options is for you. Some details can be found [here](https://github.com/facebook/relay/issues/2232).

### Server-side rendering (SSR)
For performant server-side rendering with `node 8` and above recommended to use special build of this network layer. Also you may execute `graphql` directly without http-request if you write custom middleware. All this recommendations present in following example:

Expand Down
24 changes: 20 additions & 4 deletions src/RelayNetworkLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,37 @@ import fetchWithMiddleware from './fetchWithMiddleware';
import type {
Middleware,
FetchFunction,
FetchHookFunction,
SubscribeFunction,
RNLExecuteFunction,
} from './definition';

type RelayNetworkLayerOpts = {|
subscribeFn?: SubscribeFunction,
beforeFetch?: FetchHookFunction,
|};

export default class RelayNetworkLayer {
_middlewares: Middleware[];
execute: RNLExecuteFunction;
fetchFn: FetchFunction;
subscribeFn: ?SubscribeFunction;
+fetchFn: FetchFunction;
+subscribeFn: ?SubscribeFunction;
beforeFetch: ?FetchHookFunction;

constructor(middlewares: Array<?Middleware>, subscribeFn?: SubscribeFunction) {
constructor(middlewares: Array<?Middleware>, opts?: RelayNetworkLayerOpts) {
this._middlewares = Array.isArray(middlewares) ? (middlewares: any) : [middlewares];
this.subscribeFn = subscribeFn;

if (opts) {
this.subscribeFn = opts.subscribeFn;
this.beforeFetch = opts.beforeFetch;
}

this.fetchFn = (operation, variables, cacheConfig, uploadables) => {
if (this.beforeFetch) {
const res = this.beforeFetch(operation, variables, cacheConfig, uploadables);
if (res) return res;
}

const req = new RelayRequest(operation, variables, cacheConfig, uploadables);
return fetchWithMiddleware(req, this._middlewares.filter(o => !!o));
};
Expand Down
6 changes: 6 additions & 0 deletions src/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ export type FetchFunction = (
cacheConfig: CacheConfig,
uploadables: ?UploadableMap
) => ObservableFromValue<QueryPayload>;
export type FetchHookFunction = (
operation: ConcreteBatch,
variables: Variables,
cacheConfig: CacheConfig,
uploadables: ?UploadableMap
) => void | ObservableFromValue<QueryPayload>;
// See SubscribeFunction type declaration in relay-runtime/network/RelayNetworkTypes.js
export type SubscribeFunction = (
operation: ConcreteBatch,
Expand Down

0 comments on commit c4b6f2c

Please sign in to comment.