Graph QL

Javascript

    2023-06-04 16:45

    Graph QL

    facebook에서 만든 쿼리 언어

    A query language for your API

    GraphQL은 API용 쿼리 언어이자 기존 데이터로 이러한 쿼리를 수행하기 위한 런타임입니다. 

    GraphQL은 API의 데이터에 대한 완전하고 이해하기 쉬운 설명을 제공하고 클라이언트에게 필요한 것을 정확히 요청할 수 있는 권한을 제공하며 시간이 지남에 따라 API를 더 쉽게 발전시키고 강력한 개발자 도구를 사용할 수 있도록 합니다.

    • 필요한 것을 구체적으로 요청 (필요한 것만 정확히 얻음)
    • 단일 요청으로 많은 데이터를 획득 (모든 데이터를 한 번에)
    • 엔드포인트x, 타입과 필드
    • 강력한 개발자 도구

    💡 쿼리 언어?

    SQL(Structured Query Language): 구조화된 질의어

    RDBMS(관계형 데이터베이스 관리 시스템)의 데이터 관리를 위해 설계된 언어

    DB로부터 데이터를 효율적으로 가져오기 위해

    Graph Query Language

    서버로부터 데이터를 효율적으로 가져오기 위해

    주체: 웹클라이언트

    REST API vs GraphQL

    REST API GraphQL
    리소스 리소스 모양과 크기는 서버에 의해 결정 클라이언트가 필요한 리소스를 요청
    엔드포인트 다중 엔드포인트, URL과 Method에 따라 접근할 수 있는 데이터가 다름 보통 단일 엔드포인트, GraphQL 스키마에 따라 데이터가 다름
    라우트 핸들러와 리졸버 각 요청은 정확히 하나의 경로 처리 함수를 호출 하나의 쿼리가 여러 리졸버를 호출하여 여러 리소스가 포함된 중첩 응답 구

    REST

    REST API를 사용하면 일반적으로 여러 엔드포인트에 엑세스해서 데이터를 수집해야함

    사용자/게시물/팔로워 데이터를 받아오려면

    /users/<id>
    
    /users/<id>/posts
    
    /users/<id>/followers
    
    javascript

    GraphQL

    GraphQL은 구체적인 데이터 요구 사항이 포함된 단일 쿼리로 요청 가능

    사용자/게시물/팔로워 데이터를 받아오려면

    query {
    	User(id: "er3tg439frjw"){
    		name
    		posts {title}
    		followers {name}
    	}
    }
    
    graphql

    REST API는 overfetchingunderfetching을 유발시킨다.

    사용자 이름만 알고 싶은데, /users/ 호출하면 서버가 정해둔 모든 데이터를 받아오게 된다.

    사용자 정보랑 팔로워 알고 싶은데,

    /users/ 호출하고

    /users//followers 호출해야한다.

    GraphQL은 overfetching X, underfetching X

    필요한 데이터만 요청 가능

    원하는 중첩 데이터 요청 가능

    GraphQL 이점

    프론트엔드에서 신속한 제품 이터레이션을 돌릴 수 있다.

    (서버에 매번 API 요청을 하지 않아도 됨)

    벡엔드에서 분석이 가능

    (프론트엔드에서 어떤 데이터를 가져다 쓰는지 알 수 있게 되므로)

    스키마 및 타입 시스템의 이점이 있음

    (프론트엔드와 백엔드가 사용하는 데이터 구조를 맞출 수 있음)

    Facebook은 GraphQL을 왜 만들었을까?

    같은 DB로 다양한 UI를 구상할 필요가 있었음

    Facebook의 같은 홈 화면이어도, 모바일 웹 / 모바일 앱(ios, Android) / PC 웹

    경우 각각 다른 UI로 화면을 구상할 필요가 있었음

    게시글에 대해서도 보여주는 데이터가 제각각

    이런 상황을 해소하기 위해 기존의 REST API 방식과 다른 접근을 한 것 같다

    GraphQL 실제 사용

    server

    server/app.js

    • apollo-server 설치
    npm install apollo-server
    
    bash
    • ApolloServer, gql 받아오기
    const { ApolloServer, gql } = require('apollo-server');
    
    javascript
    • GraphQL 스키마 정의
    const typeDefs = gql`
      type Product {
        category: String
        name: String
        division: String
        os: String
        model: String
        brand: String
        salesQuantity: Int
      }
    
      type Query {
        product(first: Int!): [Product]
      }
    `;
    
    javascript
    • 리졸버 함수 작성
    const resolvers = {
      Query: {
        product: (_, { first }) => {
          const products = jsonData.slice(0, first)
          return products;
        },
      },
    };
    
    javascript
    • Apollo Server 생성 및 실행
    const server = new ApolloServer({ typeDefs, resolvers });
    
    javascript

    Client

    src/Home.jsx

    • @apollo/client 설치
    npm install @apollo/client
    
    bash
    • useQuery, gql 받아오기
    import { useQuery, gql } from "@apollo/client";
    
    javascript
    • GET_PRODUCTS 정의
    const GET_PRODUCTS = gql`
      query GetProducts($first: Int!) {
        product(first: $first) {
          category
          name
          division
          os
          model
          brand
          salesQuantity
        }
      }
    `;
    
    javascript
    • 데이터 렌더링
    const Home = () => {
      const { loading, error, data } = useQuery(GET_PRODUCTS, {
        variables: {
          first: 5, // 가져올 데이터 수를 설정하세요
        },
      });
    
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error : </p>;
    
      return (
        <div>
          {data.product.map((product) => (
            <div key={product.name}>
              <h3>{product.name}</h3>
              <p>Category: {product.category}</p>
              <p>Division: {product.division}</p>
              {/* 여기에 필요한 데이터 표시 */}
            </div>
          ))}
        </div>
      );
    };
    
    javascript