GraphQL Relay 가이드 따라가기

Lee·2022년 8월 20일
1
post-thumbnail

팀 프로젝트에서 Relay를 사용한다. RelayApollo에 비해서 자료가 너무 부족하다... 정말 없다 자료가....
우선 Relay 공식 홈페이지를 참고했다.

1. CRA 만들기

 npx create-react-app relay-test-with-github    

2. GraphQL 데이터를 fetch하기(Relay 없이)

깃허브의 GraphQL 서버를 이용할것이다.

2.1 깃허브 GraphQL Authentication

깃허브 API를 사용하기 위한 토큰이 필요하다.
이곳에 들어가서 토큰을 발급 받자
.env파일을 만들어 토큰값을 설정하면 된다.

2.2: fetchGraphQL 함수 만들기

fetchGraphQL.js를 만들어서

async function fetchGraphQL(text, variables) {
  const REACT_APP_GITHUB_AUTH_TOKEN = process.env.REACT_APP_GITHUB_TOKEN;

  const response = await fetch("https://api.github.com/graphql", {
    method: "POST",
    headers: {
      Authorization: `bearer ${REACT_APP_GITHUB_AUTH_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: text,
      variables,
    }),
  });

  return await response.json();
}

export default fetchGraphQL;

안에 이런식으로 코드를 작성한뒤

2.3: 실행시키기

App.js로 가서

import { useState, useEffect } from "react";
import fetchGraphQL from "./fetchGraphQL";

function App() {
  const [name, setName] = useState(null);

  useEffect(() => {
    let isMounted = true;
    fetchGraphQL(`
      query RepositoryNameQuery {
        # feel free to change owner/name here
        repository(owner: "facebook" name: "relay") {
          name
        }
      }
    `)
      .then((response) => {
        if (!isMounted) {
          return;
        }
        const data = response.data;
        setName(data.repository.name);
      })
      .catch((error) => {
        console.error(error);
      });

    return () => {
      isMounted = false;
    };
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        <p>{name != null ? `Repository: ${name}` : "Loading"}</p>
      </header>
    </div>
  );
}

export default App;

이런식으로 실행시킨다.

이러한 결과물이 나온다.

3. Relay 사용해서 만들기

3.1 Relay 설치

npm install --save relay-runtime react-relay
npm install --save-dev relay-compiler babel-plugin-relay

3.2 스키마 다운 받기

스키마란?
그래프QL에서 데이터 타입의 집합을 스키마라고 한다.

터미널에

curl https://raw.githubusercontent.com/relayjs/relay-examples/main/issue-tracker/schema/schema.graphql > schema.graphql

이 명령어를 입력해주면 된다.

3.3 Relay 설정

package.json파일에 이런식으로 설정을 해준다.

// your-app-name/package.json
{
  ...
  "scripts": {
    ...
    "start": "yarn run relay && react-scripts start",
    "build": "yarn run relay && react-scripts build",
    "relay": "yarn run relay-compiler"
    ...
  },
  "relay": {
    "src": "./src/",
    "schema": "./schema.graphql",
    "language": "javascript"
  }
  ...
}

3.4 릴레이 런타임 구성

GraphQL 서버에 어떻게 연결할지 작성해야한다.
우선 Relay Environment을 정의해야한다.

Environment란?
해당 서버에서 검색된 데이터 캐시를 사용하여 서버(Relay 네트워크)와 통신하는 방법을 캡슐화하는것

src안에 relayEnvironment.js를 만들어보자

//relayEnvironment.js
import { Environment, Network, RecordSource, Store } from "relay-runtime";
import fetchGraphQL from "./fetchGraphQL";

async function fetchRelay(params, variables) {
  console.log(
    `fetching query ${params.name} with ${JSON.stringify(variables)}`
  );
  return fetchGraphQL(params.text, variables);
}

export default new Environment({
  network: Network.create(fetchRelay),
  store: new Store(new RecordSource()),
});

이제 App.js에서 수정을 해주면 된다.

import { Suspense } from "react";
import graphql from "babel-plugin-relay/macro";
import {
  RelayEnvironmentProvider,
  loadQuery,
  usePreloadedQuery,
} from "react-relay/hooks";
import RelayEnvironment from "./relayEnvironment";

const RepositoryNameQuery = graphql`
  query AppRepositoryNameQuery {
    repository(owner: "facebook", name: "relay") {
      name
    }
  }
`;
const preloadedQuery = loadQuery(RelayEnvironment, RepositoryNameQuery, {});
function App(props) {
  const data = usePreloadedQuery(RepositoryNameQuery, props.preloadedQuery);
  return (
    <div className="App">
      <header className="App-header">
        <p>{data.repository.name}</p>
      </header>
    </div>
  );
}

function AppRoot(props) {
  return (
    <RelayEnvironmentProvider environment={RelayEnvironment}>
      <Suspense fallback={"Loading..."}>
        <App preloadedQuery={preloadedQuery} />
      </Suspense>
    </RelayEnvironmentProvider>
  );
}

export default AppRoot;

잘못된부분이 있으면 알려주시면 감사합니다 :)

profile
프론트엔드 개발자

0개의 댓글