Graphql

No.8·2023년 4월 2일
0

Graphql(Graph Query Language)

GraphQL은 Facebook에서 처음으로 개발했고, 오픈 소스로 제공된 쿼리 언어이다.
쿼리(Query)란 데이터베이스나 파일의 내용 중 원하는 내용을 검색하기 위하여 몇 개의 코드(code)나 키(Key)를 기초로 질의하는 것을 말한다.

GraphQL의 특징

GraphQL은 HTTP를 통해 API 서버로 요청을 보내고 응답을 받는다.
응답을 받을 시, 데이터 결과를 JSON 형식으로 받는다.
GraphQL은 서버 개발자가 작성한 각 필드에 대응하는 resolver 함수로 각 필드의 데이터를 조회할 수 있다.
GraphQL은 GraphQL 라이브러리가 조회 대상 schema가 유효한지 검사한다.

schema (스키마)

데이터베이스에서 자료의 구조, 자료의 표현 방법, 자료 간의 관계를 형식 언어로 정의한 구조이다.
데이터베이스 관리 시스템(DBMS)이 주어진 설정에 따라 데이터베이스 스키마를 생성하며, 데이터베이스 사용자가 자료를 저장, 조회, 삭제, 변경할 때 DBMS는 자신이 생성한 데이터베이스 스키마를 참조하여 명령을 수행한다.

resolver (리졸버)
요청에 대한 응답을 결정해주는 함수로써 GraphQL의 여러 가지 타입 중 Query, Mutation, Subscription과 같은 타입의 실제 일하는 방식 즉 로직을 작성한다. 스키마 필드에 사용되는 함수의 실제 행동을 Resolver에서 정의한다.

장점

  • /graphql 이라는 하나의 endpoint 로 요청을 받고 그 요청에 따라 query , mutation을 resolver 함수로 전달해서 요청에 응답한다. 모든 클라이언트 요청은 POST 메소드를 사용한다.
  • 하나의 endpoint에서 쿼리를 이용해 원하는 데이터 여러개를 API에 요청하고 응답으로 받을 수 있다.
  • graphql 서버를 실행하면 POSTMAN 과 유사한 playground라는 GUI를 이용해 resolver 와 schema 를 한 눈에 보고 테스트 해 볼 수 있다.

단점

  • 캐싱이 REST보다 훨씬 복잡하다. GraphQL에선 POST 메소드만을 이용해 요청을 보내는데, 각 메소드가 가지는 캐싱을 지원 받을 수 없다.
  • 고정된 요청과 응답만 필요할 경우에는 Query 로 인해 요청의 크기가 RESTful API 의 경우보다 더 크다.

💡사용하기

REST API 의 GET 요청 -> GraphQL에서는 Query를 이용해 원하는 데이터를 요청한다.
Create, Delete와 같이 저장된 데이터를 수정하는 경우 -> Mutation을 이용해 요청한다.
구독(Subscription)이라는 개념을 제공하며 이를 이용해 실시간 업데이트를 구현할 수 있다.

Query: 저장된 데이터 가져오기
Mutation: 저장된 데이터 수정하기

  • Create: 새로운 데이터 생성
  • Update: 기존의 데이터 수정
  • Delete: 기존의 데이터 삭제

Subscription: 특정 이벤트가 발생 시 서버가 대응하는 데이터를 실시간으로 클라이언트에게 전송

// 원하는 데이터 설정후 요청 코드 
query HeroNameAndFriends {
  human(id: "1000") {
    name
    height
  }
}

// 결과
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 1.72
    }
  }
}

필드 이름을 중복해서 사용할 수 없다. 필드 이름을 중복으로 사용해서 쿼리를 해야 할 때는 별명을 붙여서 쿼리를 한다.

query HeroNameAndFriends {
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

//결과
{
  "data": {
    "empireHero": {
      "name": "Luke Skywalker"
    },
    "jediHero": {
      "name": "R2-D2"
    }
  }
}

REST API는 두가지의 문제점이 있다.

먼저,over-fetching이다.

예를 들어 영화 정보를 알기위해 url 요청 시 영화에 대한 정보 전체를 받아온다

하지만, 만약에 나는 단지 영화 제목, 영화 사진 두가지 정보만 보여주고 싶다면?
그럼에도 불구하고 선택권없이 내가 필요한 것 이상의 많은 정보를 조회할 수 밖에 없다.

이렇게 내가 데이터를 쓰던 말던 너무 많은 데이터를 받아오는 것을 over-fetching이라고 한다.

어떤 점이 안 좋을까? 그냥 데이터 다 받아오고 쓰고 싶은 것만 쓰면 안되나?
라고 생각할 수도 있다.

하지만 필요 이상의 정보를 가져오는 것은 내 database 즉 backend가 훨씬 많은 일을 해야한다는 뜻이다.

왜냐하면 말 그대로 database는 모든 정보를 주기 위해 리소스를 투여하지만 정작 내가 필요한 정보는 그 중 몇가지뿐이기 때문이다.

또한, backend에서 front로 보내야할 데이터가 많기 때문에 데이터 전송 속도 또한 느려질 수 있다.

under-fetching
두번째 문제점은 위와 반대로 우리가 필요한 정보보다 덜 받는 것이다.

위에서 조회한 영화 상세 정보에서 이 영화의 장르를 사용하고 싶을 수 있다.
장르명이 뭐지? 코미디? 로맨스? 어떤건지 체크하려고 봤더니

    "genres": [
    {
      "id": 12
    },
    {
      "id": 18
    },
    {
      "id": 878
    }

장르명이 나와있지않고 장르에 대한 id값으로 장르명을 또 조회해야하는 상황이 되었다.

그럼 영화정보 + 장르명을 알기 위해서는
요청 1. 영화 상세 정보
요청 2. 장르 id값과 일치하는 장르명

이렇게 두가지 요청이 이루어져야한다.

왜?

REST API가 내가 원하는 정보보다 적게 정보를 주었기 때문이다.

이렇게 된다면 영화 상세 정보 화면을 위해 두번의 request가 이루어진다.
즉, 이것은 로딩 시간이 느려질 가능성과 두개의 요청 중 한개의 요청이 실패할 가능성도 생길 수 있다는 말이다.

이러한 상황을 under-fetching이라고 한다.


Graphql를 써야하는 이유

over-fething 이슈를 해결한다.

GraphQL의 중요한 역할 중 한가지인데,

정보 중 특정 부분만 달라고 요청할 수 없는 REST API와는 달리 url로 데이터를 즉시 받지 않고, 필요한 데이터만 요청할 수 있다.

위 예시 들었던 영화에 대해 둘이 비교 시 이렇게 요청한다.

REST API
: 영화에 대한 정보를 줘!

GraphQL
: 영화에 대한 정보 중 제목, 영화 포스터만 줘!

이것이 바로 공식 문서에 나와있는 GrapQL의 장점이다.

under-fetching 이슈 해결

위 영화 상세 정보를 받아오는데 아래와 같이 장르 id 값만 있고 장르명이 없다.

"genres": [
{
"id": 12
},
{
"id": 18
},
{
"id": 878
}

그래서 사용자는 해당 장르 id값과 일치하는 장르명을 얻기 위해 또 한번의 request를 해야한다.

결국 영화 상세 정보를 가져오는 것과 장르명을 가져오는 api request가 두번 이루어지기 때문에 비효율적이다.

GrapQL은 우리가 필요한 정보를 한번에 받을 수 있게 해준다.
다시 말해 같은 화면에 두번의 요청을 할 필요가 없다.

이것이 바로 GrapQL 공식 문서에 나와있는 GrapQL의 특징 중 ‘ Get many resources in a single request’
이다.

profile
88888888

0개의 댓글