GraphQL

young·2022년 8월 2일
0

7/21~8/18 Section 4 TIL

목록 보기
11/22

📌 GraphQL

Graph + Query Language
API를 위한 쿼리 언어

Graph : 여러 개의 점들이 서로 복잡하게 연결되어 있는 관계를 표현한 자료 구조
node(정점, vertex)와 간선(edge)를 통해 특정한 순서에 따라 그래프를 재귀적으로 탐색할 수 있다.

엔티티: 단독으로 존재하지 못하는, 어떤 모델(e.g. 객체)의 구성요소(e.g. 프로퍼티)

GraphQL에서는 모든 데이터가 그래프 형태로 연결되어 있다고 전제한다.
그래프는 클라이언트가 필요로 하는 데이터에 따라서 트리 구조를 이룰 수 있다.

클라이언트 요청에 따라 유연하게 트리 구조의 JSON 데이터를 응답으로 전송할 수 있다.

REST API방식의 고정된 자원이 아닌 클라이언트 요청에 따라 유연하게 자원을 가져올 수 있다.

즉, 트리 구조로 쿼리 결과를 받기 위해 그래프를 탐색하는 쿼리 언어다.

GraphQL 특징

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

GraphQL vs REST API

GraphQLREST API
resource에 대한 형태 정의와 데이터 요청 방법이완전히 분리되어 있다.연결되어 있다.
resource의 크기와 형태를클라이언트 요청에서 결정한다.서버에서 결정한다.
resource를 나타내는 것은URIGraphQL Schema
작업의 유형을 나타내는 것은MethodQuery, Mutation
여러 resource에 접근하고자 할 때한 번의 요청으로 가능여러 번 요청이 필요
각 요청의 작업 처리 방식요청받은 각 필드에 대한 resolver 호출해당 엔드포인트에 정의된 핸들링 함수 호출

GraphQL의 장점

  • /graphql 이라는 하나의 endpoint로 요청을 받는다.
    요청에 따라 query, mutaition을 resolver 함수로 전달해서 요청에 응답한다.
    모든 클라이언트 요청은 POST 메소드를 사용한다.
    ➞ 쿼리를 이용해 원하는 데이터를 정확하게 요청하고 응답받음으로써 underfetch와 overfetch가 일어나지 않는다.

  • playground(GUI)를 통해 resolverschema를 한 눈에 보고 테스트해 볼 수 있다.

  • 클라이언트 구조 변경에도 서버에 지장이 없다.
    ➞ 요청 데이터를 클라이언트 단에서 결정하기 때문이다.

GraphQL의 단점

  • 캐싱이 REST보다 훨씬 복잡하다.
    POST 메소드만 사용하기 때문에 HTTP에서 각 메소드에 따라 구현된 캐싱을 지원받지 못한다.

  • 고정된 요청과 응답만 필요할 경우 query로 인해 요청의 크기가 REST API의 경우보다 커진다.


📌 GraphQL 구조

Query: 데이터 조회

Mutation: 저장된 데이터 수정 (Create / Update / Delete)

Subscription: 구독
클라이언트가 어떤 이벤트를 구독하면, 지속적인 연결을 형성하고 유지한다. 특정 이벤트가 발생하면 서버는 대응하는 데이터를 클라이언트에 실시간으로 푸시해준다.

Query

데이터를 조회하는 키워드

  • Operation type과 name을 작성해야 한다.
  • 변수를 작성하면 인수를 동적으로 받는다.

//operation type //name
query HeroNameAndFriends($변수 이름: 타입 형태) {...}
mutation CreateSomething {...}
  • 하나의 요청으로 여러 필드의 데이터를 가져올 수 있다.
//요청
query HeroNameAndFriends {
  hero {
    #name 필드와 friends 필드를 쿼리
    name
    friends {
      name
    }
  }
}


//응답
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}
  • 전달인자를 추가하면 원하는 데이터만 받아올 수 있다.
//요청
//필드와 중첩된 객체들에 대해서 id가 1000인 데이터를 받아온다.
query HumanNameAndHeight {
  human(id: "1000") {
    name
    height
  }
}


//응답
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 1.72
    }
  }
}
  • 필드 이름을 중복해서 사용할 수 없으므로 별명(Aliases)을 붙여서 쿼리한다.
    별명은 응답의 key 이름으로 쓰인다.
{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

mutation

서버 측 데이터를 수정하는 키워드

Schema/Type

  • !가 붙는다면 해당 필드는 반드시 값이 들어온다는 의미이다. (Not-Null)
    null 값이 들어올 시 서버는 실행 오류 대신 null 값을 보내준다.

Resolver

스키마 필드에서 사용되는 함수 로직을 작성한다.

요청에 대한 응답을 결정해주는 함수들을 모아서 작성하기 때문에 보통 resolvers라고 한다.


🌐 GitHub GraphQL Explorer

깃허브에서 제공하는 GraphQL API로 조회한(query) 나의 깃허브 데이터

https://docs.github.com/en/graphql/overview/explorer

깃허브 서버에 존재하는 live data를 간편하게 query할 수 있도록 도와준다.

-> 깃허브 API를 받아오는 @octokit/graphQL 활용한 앱 보러가기

profile
즐겁게 공부하고 꾸준히 기록하는 나의 프론트엔드 공부일지

0개의 댓글