[Worksheet 220519] GraphQL

방예서·2022년 5월 19일
0

Worksheet

목록 보기
43/47

GrapQL이란?

GraphQL

API를 위한 Query Language.

Query 언어?

  • SQL : 구조화된 질의어
    RDBMS(관계형 데이터베이스 관리 시스템)의 데이터 관리를 위해 설계된 언어이다.
    DB로부터 데이터를 효율적으로 가져오기 위한 언어이다.
  • GraphQL
    서버로부터 데이터를 효율적으로 가져오기 위한 언어.
    주체가 웹 클라이언트이다.

GraphQL VS REST API

https://graphcms.com/blog/graphql-vs-rest-apis

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

GraphQL이 REST API 보다 나은 점

REST API는 여러 엔드포인트에 액세스해서 데이터를 수집해야한다. (다중 엔드포인트)

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

REST API는 overfetching과 underfetching을 유발시킨다.
사용자 이름만 알고 싶은데, 모든 데이터를 가져와야한다. (overfetching)
사용자 정보랑 팔로워를 알고 싶은데, 둘다 호출해야한다. (underfetching)

GraphQL은 둘다 유발하지 않는다. 필요한 데이터만 요청하고 (overfetching 해결) 한번의 요청으로 원하는 데이터를 가져올 수 있다. (underfetching 해결)

환경설정 및 프로젝트 생성

swapi-graphql

clone 해서 npm install

url/graphiql 을 명시해주면 개발자 도구로 들어갈 수 있다.


  • introspection
    스키마의 상태 확인
{
	__schema {
    types {
      name
      kind
    }
  }
}
  • schema.graphql
    프로젝트 내의 이 파일에서 모든 스키마를 확인할 수 있다.

GraphQL 기본

https://graphql-kr.github.io/learn/

query

query는 데이터를 가지고 오는 것(fetch)

쿼리와 결과는 형태가 동일하다. (결과는 JSON 형태)

* tip! ctrl+space bar 누르면 자동완성 될 키워드 목록 보여줌

객체 중첩 참조 & 주석

쿼리는 객체를 참조할 수 있어서 여러 값을 한번에 가져올 수 있다.
쿼리에 # 으로 주석 처리도 가능하다.

별칭

쿼리의 필드 이름이 같은데 인자를 다르게 조회하고 싶은 경우에는 별칭(alias) 를 지정해주어야한다.


지정해주지 않아 오류가 난 모습

지정해주니 잘 나온다.

fragment & 작업 이름

{
  p1: person (personID: 1) {
		...personInfo	
  }
  p2: person (personID: 2) {
    ...personInfo
  }
}



fragment personInfo on Person {
  name
  homeworld {
    name
  }
  filmConnection {
    pageInfo {
      startCursor
      endCursor
    }
  }
}

fragment를 사용할 수 있다.
fragment 내에서 변수 사용도 가능하다.

query pInfo($first: Int = 3) {
  p1: person (personID: 1) {
		...personInfo	
  }
  p2: person (personID: 2) {
    ...personInfo
  }
}



fragment personInfo on Person {
  name
  homeworld {
    name
  }
  filmConnection(first: $first) {
    edges {
      node{
        title
      }
    }
  }
}

$ 표시로 변수를 선언할 수 있다.
query에서 변수를 사용하기 위해서는 앞에 query라고 명시해주어야 한다.
우리는 여태껏 익명함수를 써왔다고 생각하면 된다.
query에 이름을 지정해줄 수도 있다.

변수

인자를 동적으로 조작하기 위한 방법으로 변수를 사용한다.

  1. 쿼리안의 정적 값을 $variableName 으로 변경합니다.
  2. $variableName 을 쿼리에서 받는 변수로 선언합니다.
  3. 별도의 전송규약(일반적으로는 JSON) 변수에 variableName: value 을 전달하세요.

변수의 기본값을 명시할 수도 있다.

지시어

필드나 프래그먼트에 삽입할 수 있고 서버가 원하는 방식으로 쿼리 실행에 영향을 준다.

  • @include(if: Boolean): 인자가 true 인 경우에만 이 필드를 결과에 포함

  • @skip(if: Boolean) 인자가 true 이면 이 필드를 건너뜀


mutation

완전한 데이터 플랫폼은 서버 측 데이터를 수정할 수도 있어야한다.
데이터를 수정하는 것을 mutation이라고 한다.

Apollo graphQL 이용해서 실습을 한다.

https://studio.apollographql.com/public/SpaceX-pxxbxen/explorer?variant=current

직렬 실행

쿼리 필드는 병렬로 실행되지만 뮤테이션 필드는 하나씩 차례대로 실행됩니다.
그래서 삽입 후 바로 업데이트 하는 경우 첫번째 요청은 두번째 요청 전에 완료되는 것이 보장된다.


인라인 프래그먼트

인터페이스나 유니언 타입을 반환하는 필드를 쿼리하는 경우, 인라인 프래그먼트 을 사용해야한다.


스키마 & 타입

GraphQL 쿼리 언어는 기본적으로 객체의 필드를 선택하기 때문에 쿼리가 반환할 결과를 거의 예측할 수 있다.

하지만 서버에 요청할 수 있는 데이터에 대한 정확한 표현을 가져야지는 것이 좋다.

객체 타입과 필드

GraphQL 스키마의 가장 기본적인 구성 요소는 객체 타입이다. 객체 타입은 서비스에서 가져올 수 있는 객체의 종류와 그 객체의 필드를 나타낸다.

type Character {
  name: String!
  appearsIn: [Episode]!
}
  • Character
    GraphQL 객체 타입. 필드가 있는 타입.
    스키마 대부분은 객체 타입이다.

  • name, appearsIn
    Character 타입의 필드.

  • String
    GraphQL에 내장된 스칼라 타입.

  • [Episode]
    Episode 객체의 배열.

인자

객체 타입의 모든 필드는 0개 이상의 인자를 가질 수 있다.

스칼라 타입

어떤 필드가 구체적인 데이터로 해석되기를 원할 때 지정해주는 타입.
쿼리의 끝을 나타내며 하위 선택을 할 수 없다.

  • Int

  • Float

  • String

  • Boolean

  • ID
    ID 스칼라 타입은 객체를 다시 요청하거나 캐시의 키로써 자주 사용되는 고유 식별자를 나타낸다. ID 타입은 String 과 같은 방법으로 직렬화되지만, ID 로 정의하는 것은 사람이 읽을 수 있도록 하는 의도가 아니라는 것을 의미한다.

열거형 타입

Enums. 특정 값들로 제한 되는 특정한 종류의 스칼라 타입이다.

  1. 타입의 인자가 허용된 값 중 하나임을 검증합니다.
  2. 필드가 항상 값의 열거형 집합 중 하나가 될 것임을 타입 시스템을 통해 의사소통합니다.
enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

Episode 타입을 사용하면 정확히 NEWHOPE, EMPIRE, JEDI 중에 하나일 것이다. 지정해둔 값 중 하나가 될 것이라는 타입이다.

Non-Null

타입 뒤에 느낌표 ! 를 추가하여 Non-Null 로 표시하면 이 값은 무조건 null이 돼서는 안된다.
리스트에서도 비슷하게 동작한다.

/[String][String!][String]![String!]!
nullOOXX
[ ]OOOO
['a', 'b']OOOO
['a', 'b', null]OXOX

인터페이스

특정 필드를 포함하는 추상 타입이다.
해당 인터페이스를 구현한 타입들이 가져야 할 필드를 정의.

interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}

Character를 구현한 모든 타입은 이러한 인자와 리턴 타입을 가진 정확한 필드를 가져야한다.

유니온 타입

유니온 타입은 인터페이스와 매우 유사하지만, 타입 간에 공통 필드를 특정하지 않는다.

union SearchResult = Human | Droid | Starship

스키마에서 SearchResult 타입을 반환할 때마다 뒤에 명시된 값들을 얻을 수 있다. 유니온 타입의 멤버는 구체적인 객체 타입이어야 한다.

입력 타입

뮤테이션은 생성될 전체 객체를 전달하고자 할 수 있다. GraphQL 스키마 언어에서 입력 타입은 일반 객체 타입과 정확히 같지만, type 대신 input 을 사용한다.

input ReviewInput {
  stars: Int!
  commentary: String
}
profile
console.log('bang log');

0개의 댓글