GraphQl Start

정인아·2022년 2월 4일
0

GraphQL

목록 보기
1/1

GraphQL이란?

GraphQL은 페이스북에서 만든 API를 위한 쿼리 언어이다. REST보다 API 만드는 작업이 더 수월하다. 백엔드 언어로 node에 관심이 많은 FE로서(같은 자바 스크립트 쓰니까 정이 간다...) 후에 풀스택으로 프로젝트를 하게 된다면 꼭 GQL을 써보고 싶은 심정이다.

그렇다면 현재 널리 이용되고 있는 REST API대신에 GQL을 쓰는 걸까, 즉 GQL의 장점은 뭘까.

GQL 장점

GQL은 오버패치와 언더패치를 사전에 막아준다.
같은 회사에 재직 했던 동료가 이직을 위해 면접을 보러 다니면서 "불필요한 데이터를 왜 다 받아오냐" 라는 질문을 받았다고 한다.
현재 회사에서 진행하는 프로젝트를 작업하다보면, 서버 통신으로 넘겨 받은 데이터를 보면 불필요한 데이터처리가 가끔 고민을 하게 만든다.
(백엔드 개발자에게 보내지 말라고 말하는게 베스트일까...)
그리고 언더 패치되는 이유 때문에 불가피하게 서버 통신을 동시에 2, 3번 해야하는 경우도 생겼었다.
(시간에 쫓기는 프로젝트를 하다보니, 시간상 리팩토링 할 여유가 없었다...)

이러한 단점을 GQL은 모두 보안해주었다.
즉, GraphQL(GQL)은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것을 목표로 한다.

그리고 GQL은 스키마(Schema)를 가지는데, 이는 서버에서 정적인 타입 시스템을 사용하여 데이터를 표현하는데 사용된다.
REST API와는 다르게 EndPoint를 하나로 통합하여 사용 할 수 있다.

즉, HTTP 요청의 횟수를 줄여준다.
(이부분이 큰 장점이라고 생각한다)

GQL 단점

장점이 있다면 단점도 존재한다.
GQL은 모든 데이터를 하나의 URL에서 처리하는데 HTTP에서 제공하는 캐싱 전략을 그대로 사용 할 수 없다.

REST API는 URL마다 개별적인 데이터를 제공하게 하고, HTTP에서 제공하는 캐싱 전략을 그대로 사용이 가능하다. 단순히 HTTP 헤더를 통해서 캐싱 전략을 컨트롤 할 수 있다.

GQL 사용법

제일 중요한 사용법을 적어볼까 한다.

  1. setUp
    npm install apollo-boost @apollo/react-hooks

현재는 업데이트 된 버전으로 두가지가 하나로 통합 되었다.

    npm install  @apollo/client graphql 

index.js에서 Provider로 감싸준다.


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

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

apollo.js 파일을 만들어 가져올 api 주소 셋팅


apollo.js

    import ApolloClient from 'apollo-boost';

    const client = new ApolloClient({
        uri: "https://movieql2.vercel.app/",
        resolvers:{
            Movie: {
                isLiked: () => false
            },
            Mutation: {
                toggleLikeMovie: (_, { id, isLiked}, {cache}) => {
                        cache.writeData({
                            id: `Movie:${id}`, 
                            data: {
                            isLiked: !isLiked
                            }
                        })
                },
            }
        }
    })

    export default client;

  1. Query 문 응용

apollo-boost와 @apollo/react-hooks을 통해 각각 gql과 useQuery를 import 시키고, GET_MOVIES 라는 변수에 gql을 써서 가져오고 싶은 data 설정


Home.js

    import {gql} from "apollo-boost";
    import {useQuery} from "@apollo/react-hooks";

    const GET_MOVIES = gql`{
        movies {
            id
            medium_cover_image
            isLiked @client
        }
    }`

gql은 Home 컴포넌트 밖에서 설정 해준다

    const Home = () => {

        const { loading, error, data } = useQuery(GET_MOVIES);
        
        return (
            <Container>
                <Header>
                    <Title>Apollo 2020</Title>
                    <Subtitle>I love GraphQL</Subtitle>
                </Header>
                {(!loading && data.movies) && (
                        <Movies>
                        {
                            data?.movies?.map(m => (
                                <Movie 
                                key={m.id} 
                                isLiked={m.isLiked} 
                                id={m.id} 
                                bg={m.medium_cover_image} 
                                />
                            ))
                        }
                        </Movies>
                    )}
            </Container>
        )
    }


  1. 장점 추가!!

프론트단에서 큰 장점은 프론트단에서 api 통신 할 경우, 필요한 컬럼값을 백단에 요청하는게 아닌 프론트단에서 추가 가능


Movie.js

   const LIKE_MOVIE = gql`
        mutation toggleLikeMovie($id: Int!, $isLiked: Boolean!){
            toggleLikeMovie(id: $id, isLiked: $isLiked) @client
    }
    `

    const GET_MOVIE = gql`
        query getMovie($id: Int!){
            movie(id: $id){
                title
                medium_cover_image 
                language
                rating
                description_intro
                isLiked @client
            }
            suggestions( id:$id){
            id
            medium_cover_image
            }
        }
    `

isLiked @client 이건 원래 api에 없는 컬럼인데, 프론트단이 추가해주고 싶은 값이라서 추가 해준거임

    const Movie = ( {id, bg, isLiked} ) => {

    const [toggleMovie] = useMutation(LIKE_MOVIE, {variables: { id: parseInt(id), isLiked } })
    useQuery(GET_MOVIE, { variables: { id: +id } });

        return (
            <Container>
                <Link to={`/${id}`}>
                    <Poster bg={bg} />
                    <p onClick={toggleMovie}>{isLiked ? "Unlike" : "Like"}</p>
                </Link>
                
            </Container>
        );
    }
profile
프론트엔드 개발자

0개의 댓글