From e0222a3fa34cfc64d4e50315f8b44524a5fb47ef Mon Sep 17 00:00:00 2001 From: Konstantin Tarkus Date: Tue, 25 Apr 2017 12:32:13 +0300 Subject: [PATCH] Update docs/data-fetching.md --- docs/data-fetching.md | 76 ++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/docs/data-fetching.md b/docs/data-fetching.md index af24768d6..71fa32d55 100644 --- a/docs/data-fetching.md +++ b/docs/data-fetching.md @@ -1,30 +1,60 @@ -## Data Fetching with WHATWG Fetch - -There is isomorphic `core/fetch` module that can be used the same way in both -client-side and server-side code as follows: - -```jsx -export const path = '/products'; -export const action = async ({ fetch }) => { - const response = await fetch('/graphql?query={products{id,name}}'); - const data = await response.json(); - return ; -}; +## Data Fetching + +At a bare minimum you may want to use [HTML5 Fetch API][fetch] as an HTTP client utility for +making Ajax request to the [data API server][nodeapi]. This API is supported natively in all the +major browsers except for IE (note, that Edge browser does support Fetch). + +**React Starter Kit** is pre-configured with [`whatwg-fetch`][wfetch] polyfill for the browser +environment and [`node-fetch`][nfetch] module for the server-side environment (see +[`src/createFetch.js`](../src/createFetch.js)), allowing you to use the `fetch(url, options)` +method universally in both the client-side and server-side code bases. + +In order to avoid the the amount of boilerplate code needed when using the raw `fetch(..)` +function, a simple wrapper was created that provides a base URL of the data API server, credentials +(cookies), CORS etc. For example, in a browser environment the base URL of the data API server +might be an empty string, so when you make an Ajax request to the `/graphql` endpoint it's being +sent to the same origin, and when the same code is executed on the server, during server-side +rendering, it fetches data from the `http://api:8080/graphql` endpoint (`node-fetch` doesn't +support relative URLs for obvious reasons). + +Because of these subtle differences of how the `fetch` method works internally, it makes total +sense to pass it as a `context` variable to your React application, so it can be used from either +routing level or from inside your React components as follows: + +#### Route Example + +```js +{ + path: '/posts/:id', + async action({ params, fetch }) { + const resp = await fetch(`/api/posts/${params.id}`, { method: 'GET' }); + const data = await resp.json(); + return { title: data.title, component: }; + } +} ``` -When this code executes on the client, the Ajax request will be sent via -GitHub's [fetch](https://github.com/github/fetch) library (`whatwg-fetch`), -that itself uses XHMLHttpRequest behind the scene unless `fetch` is supported -natively by the user's browser. +#### React Component + +```js +class Post extends React.Component { + static context = { fetch: PropTypes.func.isRequired }; + handleDelete = (event) => { + event.preventDefault(); + const id = event.target.dataset['id']; + this.context.fetch(`/api/posts/${id}`, { method: 'DELETE' }).then(...); + }; + render() { ... } +} +``` -Whenever the same code executes on the server, it uses -[node-fetch](https://github.com/bitinn/node-fetch) module behind the scene that -itself sends an HTTP request via Node.js `http` module. It also converts -relative URLs to absolute (see `./core/fetch/fetch.server.js`). +#### Related articles -Both `whatwg-fetch` and `node-fetch` modules have almost identical API. If -you're new to this API, the following article may give you a good introduction: +* [That's so fetch!](https://jakearchibald.com/2015/thats-so-fetch/) by [Jake Archibald](https://twitter.com/jaffathecake) -https://jakearchibald.com/2015/thats-so-fetch/ +[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch +[wfetch]: https://github.com/github/fetchno +[nfetch]: https://github.com/bitinn/node-fetch +[nodeapi]: https://github.com/kriasoft/nodejs-api-starter