본문 바로가기

개발/graphQL

리액트로 GraphQL 써보기

공부한 것을 정리해본 글입니다.

 

GraphQL in React!

GraphQL은 URL로 요청을 보내서 정해진 데이터를 받아오는 rest api와는 달리 원하는 데이터를 찍어서 가져오는 것이 가능하다.

GraphQL은 메시지 바디에 적절한 쿼리를 담아서 post 요청을 날려서 원하는 값을 받아오게된다. 이를 리액트에서 사용하는 것을 생각해보면 fetch나 axios를 써서 메시지 바디에 위에 있는 형식대로 담아서 쓰면 되기는 하겠지만 번거로운 점이 많다. 편리한 라이브러리를 두고 굳이 저렇게 할 이유는 없다.

Apollo 라이브러리

이전 실습때 insomnia에서 post 요청으로 graphql에서 데이터를 가져왔던 것처럼 fetch나 axios를 사용해서 가져올 수는 있을 것이다. 하지만 react의 apollo 라이브러리를 활용하면 더 편하게 GraphQL 서버로부터 데이터를 가져올 수 있다고 한다.

사용해보기

import {ApolloProvider} from '@apollo/react-hooks'
import client from './apollo.js';

ReactDOM.render(<ApolloProvider client={client}><App /></ApolloProvider>, document.getElementById('root'));

index.js의 App 컴포넌트는 ApolloProvider로 감싼다. client는

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';

const cache = new InMemoryCache();
const link = new createHttpLink({
    uri: "http://localhost:4000/",
});

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

export default client;

이렇게 구성되어있다.

import React from 'react'
import {gql} from 'apollo-boost'
import { useQuery } from '@apollo/react-hooks'
import styled from "styled-components";

const GET_Member = gql`
{
   getMembers {
        name
        email
    }
}`

export default () => {
    const {loading, error, data} = useQuery(GET_Member);
    console.log(loading, data);
    return <Container>
      {loading && <h1>loading...</h1>}
      {!loading && data.getMembers && data.getMembers.map(m=><h1 key={m.name}>{m.name}</h1>)}
    </Container>
}

gql`` 내부에 playground에서 써봤던 graphql의 문법대로 적으면 된다. apollo 에서 제공해주는 useQuery 내부에 쿼리 내용을 인자로 주기만하면 결과값이 알아서 들어온다. 굉장히 편하다.. 상태값으로 관리되기 때문에 데이터가 받아와지면 렌더링이 다시 일어나게 된다.

예제에서 사용한 loading, error, data 이외에도 여러가지 반환값이 있다.

이런 상황에서 id 값을 더 가져오고 싶다면?

const GET_Member = gql`
{
   getMembers {
   		id
        name
        email
    }
}`

이렇게만 수정해주면 끝이다. REST api 와는 다르게 GraphQL 에서는 서버로부터 원하는 데이터들을 지정해서 가져올 수 있다. 단순 쿼리는 이렇게하면 되고 만약 파라미터가 필요한 쿼리라면?

type Query{
    getMembers: [Member]!
    getMember(id : Int!) : Member
    getPosts: [Post]!
    getComments: [Comment]!
}

getMember 은 id 값이 필요하다. 이때는 다음과 같이 해주면 된다.

const GET_MEMBER = gql`
query getMember($id: Int!) { //여긴 아폴로 클라이언트 부분
    getMember(id : $id) {    // 여기부터
        id
        name
    }                       // 여기까지가 서버에 나가는 쿼리
}`


const {loading, data} = useQuery(GET_MEMBER, {
        variables:{ id:+id }
    });

$ 기호를 통해서 파라미터 바인딩이 이루어진다. 전체적으로 schema의 스펙과 동일하게 맞춰주면 된다.

 

코드 정리하기

데이터를 받아오고나서 화면에 띄워줄때

export default () => {
    const {loading, error, data} = useQuery(GET_Member);
    console.log(loading, data);
    return <Container>
      {loading && <h1>loading...</h1>}
      // ****
      {!loading && data && data.getMembers && data.getMembers.map(m=><h1 key={m.name}>{m.name}</h1>)}
      // ****
    </Container>
}

!loading && data && 하면서 &&로 잇는것 보다는 optional chaining을 쓰는것이 더 좋다.

{!loading && data?.getMembers.map(m => <Movie key={m.name} id={m.id}>{m.name}</Movie>)}

코드가 많이 깔끔해졌다!

 

 

'개발 > graphQL' 카테고리의 다른 글

GraphQL로 rest api 감싸기  (0) 2021.09.01
GraphQL이란?  (0) 2021.08.31