본문 바로가기

API

GraphQL header 추가하기

728x90

https://boxercat.tistory.com/entry/GraphQL-vs-REST-API

 

GraphQL vs REST API

GraphQL은 API를 위한 Query Language이다. 우리에게 더 익숙한 REST API와 GraphQL의 차이점이 무엇인지 알아보고, Next.js에서 GraphQL을 사용하는 방법에 대해 알아보겠다. REST API Representational State Transfer의 약

boxercat.tistory.com

이 글을 보고 프로젝트에 적용해보려다가 401 에러가 뜨는 경우가 있을텐데 대부분 header에 Authorization을 추가하지 않았기 때문일 겁니다. 포켓몬 정보야 API key가 별도로 필요하지 않지만, API key가 존재하는 API나 auth가 필요한 API의 경우 Authorization을 달아주지 않았을 때 401에러가 뜰 수 있습니다.

결론을 먼저 말씀드리자면 저는 다음과 같이 구현했습니다. 

import type { DocumentNode } from '@apollo/client'
import { ApolloClient, InMemoryCache, ApolloLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import { createHttpLink } from '@apollo/client/link/http'
import { auth } from './auth'
import { adminBaseUrl } from './vars'

const httpLink = createHttpLink({
  uri: adminBaseUrl
})

const authLink = setContext(async (_, { headers }) => {
  const session = await auth()
  return {
    headers: {
      ...headers,
      authorization: session?.token.accessToken
    }
  }
})

const link = ApolloLink.from([authLink.concat(httpLink)])

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link
})

/**
 * @description
 * Fetch data from GraphQL server.
 *
 * @param query - GraphQL query using gql from @apollo/client
 * @param variables - GraphQL query variables
 *
 * @example
 * const problems = await fetcherGql(GET_PROBLEM, {
 *  groupId: 1,
 *  contestId: 1
 * }).then((data) => data.getContestProblems as ContestProblem[])
 */

export const fetcherGql = async (
  query: DocumentNode,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  variables?: Record<string, any>
) => {
  const { data } = await client.query({
    query,
    variables,
    context: {
      fetchOptions: {
        next: { revalidate: 0 }
      }
    }
  })
  return data
}

httpLink에는 GraphQL endpoint, authLink에는 header에 authorization을 넣어서 concat 해서 link로 사용하면 401에러 없이 GraphQL을 불러올 수 있습니다.

추가로 fetcherGql에서 prop이 2가지가 있는데 query는 GraphQL 쿼리이며, variables는 쿼리에 전달되는 변수 객체입니다.

또한 fetchOptions에 revalidate를 설정해줄 수 있는데 revalidate를 0으로 지정할 경우 캐시 사용하지 않고 매번 데이터를 새로 불러오도록 하는 옵션입니다. 

728x90