Search code examples
reduxredux-thunkreact-starter-kit

What is fetchKnowingCookie middleware used for in the react starter kit?


Looking through the createHelpers.js code in the react starter kit, I see that it's creating a grapqlRequest and a fetchKnowingCookie method in the middleware.

https://github.com/kriasoft/react-starter-kit/blob/feature/redux/src/store/createHelpers.js

What exactly is this doing? Is it adding a cookie header to server rendered fetch requests?

I see that it's also passing in the functions into the middleware via thunk.withExtraArgument, what does that extra line do? Does it mean the fetch with cookies function becomes available from redux async actions?

import fetch from '../core/fetch';

function createGraphqlRequest(fetchKnowingCookie) {
  return async function graphqlRequest(query, variables) {
    const fetchConfig = {
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query, variables }),
      credentials: 'include',
    };
    const resp = await fetchKnowingCookie('/graphql', fetchConfig);
    if (resp.status !== 200) throw new Error(resp.statusText);
    return await resp.json();
  };
}

function createFetchKnowingCookie({ cookie }) {
  if (!process.env.BROWSER) {
    return (url, options = {}) => {
      const isLocalUrl = /^\/($|[^/])/.test(url);

      // pass cookie only for itself.
      // We can't know cookies for other sites BTW
      if (isLocalUrl && options.credentials === 'include') {
        const headers = {
          ...options.headers,
          cookie,
        };
        return fetch(url, { ...options, headers });
      }

      return fetch(url, options);
    };
  }

  return fetch;
}

export default function createHelpers(config) {
  const fetchKnowingCookie = createFetchKnowingCookie(config);
  const graphqlRequest = createGraphqlRequest(fetchKnowingCookie);

  return {
    fetch: fetchKnowingCookie,
    graphqlRequest,
    history: config.history,
  };
}

Solution

  • It is injecting a modified version of fetch into the thunk middleware being applied to the store.

    react-starter-kit is using node-fetch to handle fetch calls on the server. Unfortunately, node-fetch doesn't support cookies.

    Every time a user makes a request to the server, a new store is configured using req.headers.cookie. That cookie object will then be used in any fetch requests made by thunks in your application, getting around the node-fetch limitation.