Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Enable customizing networking library reducing bundle size #113

Merged
merged 2 commits into from Jul 28, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 39 additions & 16 deletions docs/guides/custom-networking.md
Expand Up @@ -4,45 +4,66 @@ sidebar_label: Custom networking library
---
The default `fetch()` implementation uses [superagent]() due to it's server-side support
and excellent builder-pattern api. However, a simple overriding of the `fetch()` function
will enable you to use any networking library you please.
will enable you to use any networking library you please. By extending from `SimpleResource`
instead of `Resource` you can potentially reduce your bundle size by enabling the superagent
library to be tree-shaken away.

### Default fetch with superagent:

```typescript
import request from 'superagent';
import { Method } from '~/types';

import SimpleResource from './SimpleResource';

/** Represents an entity to be retrieved from a server. Typically 1:1 with a url endpoint. */
export default abstract class Resource extends SimpleResource {
/** A function to mutate all requests for fetch */
static fetchPlugin?: request.Plugin;

/** Perform network request and resolve with json body */
static async fetch<T extends typeof Resource>(
static fetch<T extends typeof Resource>(
this: T,
method: Method = 'get',
method: Method,
url: string,
body?: Readonly<object>,
) {
let req = request[method](url).on('error', () => {});
if (this.fetchPlugin) req = req.use(this.fetchPlugin);
if (body) req = req.send(body);
const json = (await req).body;
return json;
return req.then(res => {
if (process.env.NODE_ENV !== 'production') {
if (!res.type.includes('json') && Object.keys(res.body).length === 0) {
throw new Error('JSON expected but not returned from API');
}
}
return res.body;
});
}
}
```

Here are examples using other popular networking APIs:

## [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
## Fetch

[Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)

```typescript
import { Resource, Method } from 'rest-hooks';
import { SimpleResource, Method } from 'rest-hooks';

export default abstract class FetchResource extends Resource {
export default abstract class FetchResource extends SimpleResource {
/** A function to mutate all request options for fetch */
static fetchOptionsPlugin?: (options: RequestInit) => RequestInit;

/** Perform network request and resolve with json body */
static async fetch<T extends typeof Resource>(
static async fetch<T extends typeof SimpleResource>(
this: T,
method: Method = 'get',
method: Method,
url: string,
body?: Readonly<object>
) {
let options = {
let options: RequestInit = {
method: method.toUpperCase(),
credentials: 'same-origin',
headers: {
Expand All @@ -59,17 +80,19 @@ export default abstract class FetchResource extends Resource {
}
```

## [Axios](https://github.com/axios/axios)
## Axios

[Axios](https://github.com/axios/axios)

```typescript
import { Resource, Method } from 'rest-hooks';
import { SimpleResource, Method } from 'rest-hooks';
import axios from 'axios';

export default abstract class AxiosResource extends Resource {
export default abstract class AxiosResource extends SimpleResource {
/** Perform network request and resolve with json body */
static async fetch<T extends typeof Resource>(
static async fetch<T extends typeof AxiosResource>(
this: T,
method: Method = 'get',
method: Method,
url: string,
body?: Readonly<object>
) {
Expand Down