Noh | エンジニア向け情報共有コミュニティ
Signup / Login

Manipulating request headers and response headers with Apollo Client and URQL

graphql
javascript
typescript
react

投稿日: 2024/06/25

更新日: 2024/07/02

This article is a translation of the following article.

https://noh.ink/articles/oyI7tWGjqCmyhfzQowVq

Apollo Client and URQL are well-known GraphQL client packages.

I have written code to set values in a request header and retrieve values from a response header.

This time, for example, we will set and retrieve CSRF tokens.

The code I am writing is in Typescript, so please translate it effectively for those who write in Javascript.

The Router component that appears is a ReactRouter, but it can be anything.

In addition, sessionStorage mentioned in the explanation is used to store data in the browser. It is not related to server-side sessions or cookies.
Link to sessionStorage documentation

Example of Apollo Client

import { ApolloClient, InMemoryCache, ApolloProvider, HttpLink, ApolloLink, } from "@apollo/client"; import Router from "./Router"; const App: React.FC = () => { const httpLink = new HttpLink({ uri: "/graphql" }); const middlewareLink = new ApolloLink((operation, forward) => { operation.setContext(({ headers = {} }) => ({ headers: { ...headers, "X-CSRF-Token": sessionStorage.getItem("csrfToken") || document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]') ?.content || null, }, })); return forward(operation); }); const afterwareLink = new ApolloLink((operation, forward) => { return forward(operation).map((response) => { const context = operation.getContext(); const headers = context.response.headers; if (headers && headers.get("csrf-token")) { sessionStorage.setItem("csrfToken", headers.get("csrf-token")); } return response; }); }); const client = new ApolloClient({ link: ApolloLink.from([middlewareLink, afterwareLink, httpLink]), cache: new InMemoryCache(), }); return ( <ApolloProvider client={client}> <Router /> </ApolloProvider> ); }; export default App;

middlewareLink sets the CSRF token in the request header.

If a token is stored in sessionStorage, it will be used. Otherwise, the token found in the <meta> tag within the HTML <head> will be used.

afterwareLink is taking the CSRF token from the response header.

If a token exists in the response header, it is saved in the sessionStorage.

Example of URQL

import { createClient, Provider } from "urql"; import Router from "./Router"; const App: React.FC = () => { const client = createClient({ url: "/graphql", fetchOptions: () => { const csrfToken = sessionStorage.getItem("csrfToken") || document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]') ?.content || ""; return { headers: { "X-CSRF-Token": csrfToken, }, }; }, fetch: (...args) => fetch(...args).then((response) => { const csrfToken = response.headers.get("csrf-token"); if (csrfToken) { sessionStorage.setItem("csrfToken", csrfToken); } return response; }), }); return ( <Provider value={client}> <Router /> </Provider> ); }; export default App;

You can set values in the request headers using the fetchOptions option.

You just need to write a function that returns a hash like headers: { ... } as shown in the official documentation, and then include the CSRF token in the hash.

You can obtain a value from the response headers using the fetch option.

Just like with Apollo Client, if there is a token in the response header, it is stored in the sessionStorage.

Reference

Table of Contents