GraphQL에서의 모든 데이터는 그래프 형태로 연결되어있다고 전제한다.
그리고 이를 통해 클라이언트 요청에 따라 트리 구조의 JSON 데이터를 응답으로 전송할 수 있다.
GraphQL은 클라이언트 요청에 따라 🌈유연하게 자원을 가져올 수 있다.
즉, 트리 구조로 쿼리 결과를 받기 위해 그래프를 탐색하는 언어이다.
query {
책(ISBN이 "9791160507621") {
책 이름
저자 {
이름
}
옮김
}
}
//이 요청을 보내면
{
책 : {
책 이름 : "커리어스킬",
저자 : [
{ 이름 : "존 손메즈"}
옮김 : "이미령"
]
}
}
//이렇게 응답(쿼리)이 온다.
장점
하나의 endpoint 요청(
/graphql
, 모든 클라이언트 요청은 POST 메서드 사용)
원하는 데이터 정확하게 요청하고 얻을 수 있음
playground라는 GUI를 이용해 resolver, schema 한눈에 볼 수 있음
클라이언트 구조 변경이 수월함
단점
캐싱이 REST보다 복잡하다.(Apollo 엔진의 캐싱과 영속 쿼리로 보완)
고정된 요청과 응답만 필요한 경우에 RESTful API보다 요청 크기가 커진다.
Query: 데이터 가져오기
Mutation: 데이터 수정하기
Create: 새로운 데이터 생성
Update: 데이터 수정
Delete: 데이터 삭제
Subscription(구독): 특정 이벤트가 발생 시 대응하는 데이터를 실시간으로 클라이언트에게 전송
필드
{ hero { #필드 hero name } } //-> { #쿼리와 결과가 같은 모양을 하고 있다. "data": { #string 타입 반환. "hero": { "name": "betman", "family": [ {"name": "Night wing"}, {"name": "Red hood"}, {"name": "Red robin"}, {"name": "Robin"} ] } } }
#으로 주석
,으로 필드 중첩전달인자 Arguments
필드에 인수를 전달하는 부분을 추가하면 쿼리의 필드 및 중첩된 객체들에 전달해 원하는 데이터만 받을 수 있다.
별명 Aliases
필드 이름을 중복해서 사용할 수 없다. 필드 이름을 중복으로 사용해서 쿼리를 해야 할 때에는 별명을 붙이면 된다.
{ betmanFamily: hero(title: betman family) { name } supermanFamily: hero(title: superman family) { name } }
오퍼레이션 네임 Operation name
약식으로 작성하지 않는 한 반드시 필요하다.
query, mutation, subscription, describes ..등query HeroFamily { //앞의 `query`가 오퍼레이션 네임. hero { name family { name } } }
변수 Variables
오퍼레이션 네임 옆에 변수를
$변수이름:타입
이런식으로 정의.
뒤에 !가 붙기도 한다.($ep: Episode! 일때 ep는 반드시 Episode여야한다는 의미)
구성요소: 객체의 종류, 객체 유형
type Character {
name: String!
appearsIn: [Episode!]!
}
요청에 대한 응답을 결정해주는 함수.
스키마를 정의한 후 그 스키마 필드에 사용되는 함수의 실제 행동을 Resolver에서 정의한다.
Query: {
human(obj, args, context, info) {
return context.db.loadHumanByID(args.id).then(
userData => new Human(userData)
)
}
}