GrapQL

박재현·2023년 6월 27일
0

🔎 GrapQL이란? (feat. REST API와의 차이점)

  • GraphQL 은 API를 위한 쿼리 언어(Query Language)
  • 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임
  • GraphQL은 특정한 데이터베이스나 특정한 스토리지 엔진과 관계되어 있지 않으며 기존 코드와 데이터에 의해 대체됩니다.

📌 쿼리언어

쿼리 언어는 정보를 얻기 위해 보내는 질의문(Query)를 만들기 위해 사용되는 컴퓨터 언어이다. 가장 잘 알려져있는 예시로는 데이터베이스 시스템에 저장된 데이터를 가져오기 위해 사용하는 SQL이 있다.

📌 GraphQL(Graph Query Language)

SQL: 서버가 데이터베이스에서 데이터를 가져오는 목적
GraphQL: 클라이언트가 서버에서 데이터를 가져오는 목적


🔎 GraphQL vs REST API

💡 엔드포인트

REST API

=> 하나의 엔트포인트가 응답하는 값이 정해져 있다

GraphQL

=> 하나의 엔트포인트에서 요청하는 쿼리에 따라 다른(원하는) 응답(Response)을 받을 수 있다.
(Database TABLE에 SELECT 쿼리로 WHERE, IF 등의 조건문을 통해 원하는 데이터를 가져오는 것과 비슷하다)


/swapi.dev/api/people API에서 id: 1로 등록된 유저의 정보를 가져오고자 하는데
내가 원하는 데이터는 name, heghit, mass 이 3개 값만 필요하다

// REST API request
GET, https://swapi.dev/api/people/1

// REST API response
{
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "http://swapi.dev/api/planets/1/",
    "films": ["http://swapi.dev/api/films/1/", "http://swapi.dev/api/films/2/", "http://swapi.dev/api/films/3/", "http://swapi.dev/api/films/6/"],
    "species": [],
    "vehicles": ["http://swapi.dev/api/vehicles/14/", "http://swapi.dev/api/vehicles/30/"],
    "starships": ["http://swapi.dev/api/starships/12/", "http://swapi.dev/api/starships/22/"],
    "created": "2014-12-09T13:50:51.644000Z",
    "edited": "2014-12-20T21:17:56.891000Z",
    "url": "http://swapi.dev/api/people/1/"
}
// GraphQL request
query {
    person(personID: 1) {
        name
        height
        mass
    }
}

// GraphQL response
{
    "data": {
        "person": {
            "name": "Luke Skywalker",
            "height": 172,
            "mass": 77
        }
    }
}

🔎 핵심 개념

Query/Mutation

Query

  • 데이터를 단순히 받아올 때 주로 사용. CRUD 에서 Read에 해당하는 기능
  • HTTP의 GET과 비슷
  • 여러개의 Query를 요청했을 때 쿼리가 병렬로 실행됨

Mutation

  • 데이터 조작하는 쿼리에 주로 사용. CRUD에서 Create, Update, Delete에 해당하는 기능
  • HTTP의 POST와 비슷
  • 여러개의 Mutation을 요청했을 때 쿼리가 순차적으로 실행됨 (한 요청에 두개의 Mutation이 있는경우 순차적 실행)

오퍼레이션

일반 쿼리

  • 변수를 직접 입력

오퍼레이션

  • 쿼리용 함수 라고 생각하면 됨
  • 프로그래밍으로 변수에 값을 할당 할 수 있는 함수 인터페이스가 존재
  • 이 개념 덕분에 REST API를 호출할때와 다르게, 한번의 인터넷 네트워크 왕복으로 원하는 모든 데이터를 가져 올 수 있다.

Operation 을 사용한 Request

  • Operation type: 어떤 유형의 작업을 수행하고자 하는지 표시합니다. query, mutation 또는 subscription입니다.
  • Operation name: 오퍼레이션에 이름을 부여합니다. 프로그래밍 언어의 함수 이름과 유사합니다. 이름을 정해두면 네트워크 로그나 GraphQL 서버에서 문제가 발생했을 시 내용을 해독할 필요 없이 코드 베이스에서 해당 쿼리를 쉽게 찾을 수 있습니다.
  • Variable definitions: 쿼리에 필요한 변수입니다. GraphQL 서버로 쿼리를 보낼 때 실제 쿼리는 동일하지만 요청마다 변경되는 동적 부분이 있을 수 있습니다. 이때 변수가 사용됩니다. 이 변수는 쿼리와 별도로 전송되며 전송 포맷은 JSON입니다.
query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

🔎 GraphQL 장단점

💡 기존 REST API 통신의 한계

  • 특정 기능을 위해 여러번 API가 호출됨
  • 특정 요청에 Fit한 응답을 돌려주기 위해 API를 새로 만들어야함
  • API 유지보수의 어려움 (iOS, Android에 따라 일일이 API 따로 구현해야함)

💡 장점

  • HTTP 응답 사이즈(리소스)를 줄일 수 있다.

    • Restful의 경우 응답의 형태가 정해져있기 때문에 필요한 정보만 부분적으로 요청하는 것이 힘들고, 자연스럽게 데이터의 사이즈가 클 수 밖에 없다. Facebook이 GraphQL을 개발한 초기 이유 중 하나는 모바일 사용의 증가라고 한다. GraphQL을 사용함으로써 응답 데이터 사이즈를 최소화하여 모바일 환경의 부담을 줄일 수 있다.
  • HTTP 요청 횟수를 줄일 수 있다.

    • RESTful의 경우 필요한 리소스 별로 요청 해야하고, 필요한 데이터들이 부분적으로 나눠서 개발되어 있다면 그만큼 요청 횟수가 늘어난다. 하지만 GraphQL은 원하는 정보를 하나의 쿼리에 모두 담아 요청 할 수 있다.
  • 프론트엔드와 백엔드 개발자의 부담을 덜 수 있다.

    • Restful API를 사용한다면 프론트엔드 개발자는 API의 request/response 형식에 의존하게 된다. 따라서 새로운 엔드포인트를 효율적이게 개발하기 위해서는 프론트엔드와 백엔드 개발자의 커뮤니케이션이 강제되는 경우가 많았다.
      하지만 GraphQL은 request/response 의존도가 많이 없기 때문에, 개발자들의 API 개발 부담을 덜 수 있다.

💡 단점

요약

  • 고정된 요청과 응답만 필요할 때에는 query로 인해 요청의 크기가 Restful보다 커질 수 있다.
  • 캐싱이 REST보다 복잡하다.
  • 파일 업로드 구현 방법이 정해져있지 않아 직접 구현해야 한다.

  • GraphQL 스키마에서 필드를 정확하게 모두 명시해줘야하므로 번거로운 상황이 생긴다
    • DTO는 상속을 통해 필드 생략이 가능한데, GraphQL 스키마에서 필드 상속 또는 필드 생략할 수 없어서 필드를 모두 다 적어줘야한다
    • Map, Object를 사용하지 못한다
    • 하나의 필드만 담겨있어도 모든 응답을 객체로 만들어야 한다.
    • REST API는 ResponseEntity, HashMap<String,Any>로 유연하게 리턴 가능한데, GraphQL은 [Friend] List라는 의미 이런식으로 정확히 정의해야한다.
    • DTO의 필드명이 변경되면 GraphQL 스키마 필드를 수정해줘야한다
  • Client에서도 모든 필드를 작성해야한다
    • Client에서 스키마를 가지고 있어야 요청할 수 있다.
    • Backend에서 필드 수정이 일어나면 Client도 다시 배포해야한다
    • 즉, 장점에서 백엔드/프론트엔드간 커플링 감소되어 유연성 증가한다고 써놨지만, 둘 다 동일한 스키마를 가지고 있어야 한다는 점에서는 여전히 커플링 되어있다고 할 수 있다.
  • BackEnd 입장에서 설정해줄게 너무 많다.
    • Query/Mutation 파일에 작성한 메서드 및 리턴타입과 스키마 파일을 무조건 동기화 시켜야하기 때문에 REST API 보다 작성할 파일이 더 많다
  • 파일업로드 직접 구현
    • GraphQL은 원칙적으로 multipart/from-data 형식을 받을 수 없고 application/json 형식만 받을 수 있음
      GraphQL에서는 multipart -> json으로 바꿔 전달해주는 미들웨어나 패키지를 사용해야하기 때문에 까다로움
  • 필드 타입(스칼라 타입)이 한정적이다
    • 지원하는 필드타입 확인하러 가기
    • 특히 HashMap이 지원이 안되기 때문에 개발할 때 불편했다..

정리

REST-API의 문제점

  1. 수많은 엔드 포인트

    REST-API를 사용할 때는 각 API 요청에 맞는 수많은 엔드 포인트가 필요

    POST /boards    => 게시글 등록 함수: () => {  }
    GET  /boards    => 게시글 조회 함수: () => {  }
    GET  /products  => 상품 목록 조회 함수: () => {  }
  2. REST-API의 UnderFetching 문제

  • 하나의 페이지를 구성하는데 회원 정보, 게시글 목록, 상품 목록이 필요하다면,
    REST-API를 사용했을 때는 하나의 페이지를 완성하기 위해서 총 세번의 요청을 반드시 수행해야 합니다.
    -> 이러한 문제를 UnderFetching
  1. REST-API의 OverFetching 문제
  • 게시글 목록에는 게시글 조회를 통해 받아와지는 데이터 모두가 필요하진 않음
    하지만 REST-API는 백엔드 서버에서 응답으로 보낸, 당장 우리에게는 불필요한 데이터까지 모두 받아오게
    -> 이러한 문제를 OverFetching

=> 이러한 문제를 개선하고자 나온 것이 GraphQL

  1. 수많은 엔드 포인트
    GraphQL은 모든 요청의 엔드 포인트를 POST /graphql로 통일하였습니다.
  2. REST-API의 UnderFetching 문제
    GraphQL은 한번의 요청을 통해 여러 API에 접근하는 것이 가능
  3. REST-API의 OverFetching 문제
    GraphQL은 원하는 데이터만을 응답으로 요청 가능

GraphQL은 RestAPI를 활용한 방식이고, 항상 POST 요청

이러한 특징으로 인해 GraphQL을 사용할 때는 주의해야 할 점

  1. GraphQL은 항상 POST 방식
    body에 query를 담아 요청하는 방식으로, 항상 body를 전달할 수 있도록 POST 방식으로 요청
  2. 응답으로 항상 200을 받습니다.(타입 에러 제외)
  • GraphQL은 한번에 여러 API에 요청 가능
  • 하지만 어떤 요청이 성공하고 실패 했는지 파악이 어렵기 때문에 언제나 상태 코드 200을 돌려 받게 됨
    다만, 요청 과정에서 올바른 요청이 진행될 수 없는 타입 에러는 제외


참고 사이트 🙏🏻

0개의 댓글

관련 채용 정보