brew install --cask graphql-playground
API 엔드포인트를 플레이그라운드 툴에 붙여넣거나, 브라우저에서 URL 을 치고 인터페이스로 들어감
ex) 스노투스 GraphQL 플레이그라운드 인터페이스
- https://snowtooth.moonhighway.com/
query {
allLifts {
name
status
}
}

쿼리 작업 두개를 같은 문서에 쓰더라도 하나의 동작만 실행 가능
데이터를 한번에 모두 받아오고 싶다면
query listsAndTrails {
liftCount(status: OPEN)
allLifts {
name
status
}
allTrails {
name
difficulty
}
}
Query - GraphQL 타입 == 루트 타입 (타입 하나가 곧 하나의 작업 -> 작업이 곧 쿼리 문서의 루트)
query 에 사용할 수 있는 필드는 API 스키마에 정의
API 문서에 Query 타입으로 선택할 수 있는 필드 나열
쿼리 작성 시 중요한 것은 필요한 필드만 요청하는 것
셀렉션 세트 - 쿼리를 작성할 때 필요한 필드를 중괄호로 감싼 것
안에 들어간 필드는 GraphQL 타입(Query)와 직접적 연관이 있음 - 필드 모두 Query 타입 안에 정의됨
셀렉션 세트는 중첩가능
# 응답 객체의 필드명 다르게 받고 싶을경우 필드명에 별칭 부여
query listsAndTrails {
...
chairLits: allLifts {
liftName: name
status
}
...
}
GraphQL 쿼리 결과에 대한 필터링 작업을 하고싶을 경우 쿼리 인자를 사용한다.
query listsAndTrails {
liftCount(status: CLOSED)
chairLits: allLifts(status:CLOSED) {
liftName: name
status
}
...
}
데이터를 선택하는 용도로 인자를 활용할 수도 있음
개별 리프트 상태에 대한 쿼리 작성을 원할 경우, 리프트의 아이디를 사용해 해당 리프트 선택
query jazzCatStatus {
Lift(id: "jazz-cat"){
name
status
night
elevationGain
}
}
다른 프로그래밍 언어에서 원시 타입과 비슷, 쿼리 셀렉션 세트의 잎(leaves)이 되어주는 타입
정수, 실수 -> JSON 숫자 데치터 반환
문자열, 고유 식별자 -> JSON 문자열 데이터 반환
스키마에 정의한 필드를 그룹으로 묶어 둔 것, 필드는 스칼라, 객체 타입 둘중 하나에 속함
응답으로 반환되어야 할 JSON 객체의 형태를 하고 있음
특정 객체가 있을 때, 이와 관련된 객체 세부 정보를 얻어내는 쿼리를 작성해 이들 객체를 서로 연결할 수 있음
# trailAccess는 Lift 타입 안에 있는 필드여서 API 에서는 부모 객체인 재즈 캣 Lift 의 정보를 활용해
# 특정 코스만 필터링
# 리프트와 코스 데이터 타입 사이의 일대다 연결 관계
query trailsAccessedByJazzCat {
Lift(id: "jazz-cat"){
capacity
trailAccess {
name
difficulty
}
}
}
프래그먼트 - 셀렉션 세트의 일종, 여러번 재사용할 수 있음
프래그먼트는 fragment 식별자를 사용하여 만듬
프래그먼트는 특정 타입에 대한 셀렉션 세트이므로 어떤 타입에 대한 프래그먼트인지 정의에 꼭 써줘야 함
프래그먼트 필드를 다른 셀렉션 세트에 추가하려면 "...이름" 과 같이 사용
프래그먼트를 다른 필드와 함께 쓸수도 있음
같은 타입에 대한 프래그먼트를 여러 개 쓸 수도 있음
한 차례의 수정으로 쿼리의 셀렉션 세트를 한 번에 바꿀 수 있다는 것이 프래그먼트의 장점
#프래그먼트로 쿼리에서 중복되는 부분을 줄일 수 있음
아래 예시에서는 프래그먼트를 liftInfo 라고 명명했으며, Lift 타입에 대한 셀렉션 세트임
query {
Lift(id: "jazz-cat"){
...liftInfo
elevationGain
trailAccess {
name
difficulty
}
}
Trail(id: "river-run") {
name
difficulty
accessedByLifts {
...liftInfo
}
}
}
fragment liftInfo on Lift {
name
status
capacity
night
elevationGain
}
타입 여러 개를 한 번에 리스트에 담아 반환하고 싶을때 사용함, 두 가지 타입을 하나의 집합으로 묶는 것
이름이 없는 프래그먼트, 쿼리 안에서 특정 타입에 바로 셀렉션 세트를 넣어버린다.
유니언 타입에서 여러 타입의 객체를 반환할때, 각각의 객체가 어떤 필드를 반환할 것인지 정할 때 사용
# 이름이 있는 프래그먼트를 사용해도 된다.
query schedule{
agenda {
...on Workout {
name
reps
}
...on StudyGroup {
name
subject
students
}
}
}
필드 하나로 객체 타입을 여러개 반환할 때 사용, 추상적인 타입이며 유사한 객체타입을 만들 때 구현해야 하는 필드 리스트를 모아둔 것
인터페이스를 가지고 타입을 구현할 때는 인터페이스에 정의된 필드를 모두 넣어야 하며
몇가지 고유한 필드도 넣을 수 있음
#agenda 필드의 항목은 모두 ScheduleItem 인터페이스를 반환함
#여기에는 name, start, end 필드가 정의 - 이들은 모두 ScheduleItem 인터페이스를 사용하여 만든 객체타입에 정의되어야 함
#agenda 가 반환하는 StudyGroup 과 Workout 타입이 이 인터페이스를 바탕으로 만들어 짐
#agenda 필드가 반환하는 타입 종류의 개수는 상관없음
# 프래그먼트를 사용하여 특정 객체 타입이 반환될 때, 필드가 더 들어갈 수 있도록 함
query schedule {
agenda {
name
start
end
...on Workout {
reps
}
}
}
데이터를 새로 쓸때 사용, 뮤테이션 하는 방법은 쿼리 작성과 비슷하며 이름을 붙여야 함
객체 타입이나 스칼라 타입의 반환 값을 가지는 셀렉션 세트가 들어감
쿼리와 다른점은 데이터를 뮤테이션 하면 백엔드 데이터에 영향을 줌
# 위험한 코드
mutation burnItDown{
deleteAllData
}
mutation createSong{
addSong(title: "No Scrubs", numberOne: true, performerName:"TLC") {
id
title
numberOne
}
}
뮤테이션 필드가 객체를 반환하도록 만들려면 셀렉션 세트를 추가해야 함
문제가 발생했다면 객체 대신 에러가 담긴 JSON 응답이 반환
mutation closeLift {
setLiftStatus (id: "jazz-cat", status: CLOSED) {
name
status
}
}
정적값을 변수로 대체하여 계속해서 바뀌는 동적인 값을 넣을수도 있음
변수명 앞에는 $ 문자가 붙는다
mutation createSong($title:String! $numberOne:Int $by:String!) {
addSong(title:$title, numberOne:$aunberOne, performerNsne:$by) {
id
title
runberOne
}
}
변수는 쿼리 변수용 창에 JSON 형식으로 따로 설정
{ "title" : "No Scrubs", "numberOne" : true, "by" : "TLC" }
데이터 서브스크립션을 하면 GraphQL API를 사용해 실시간 데이터 변경 내용을 받을 수 있음 ex)Live Likes
클라이언트에서 받을 수 있는 데이터 변경 내용은 subscription 타입 아래 필드로 정의되어 API 스키마에 들어감
#뮤테이션을 실행하여 Lift 의 값을 변경하면 해당 리프트의 name, capacity, status 값이 서브스크립션에 전송된다.
subscription {
liftStatusChange {
name
capacity
status
}
}
API 스키마의 세부 사항에 관한 쿼리를 작성할 수 있음
GraphQL 플레이그라운드 인터페이스에서 GraphQL 문서를 보여 줄 수 있는 것도 이 덕분
어떤 GraphQL 타입을 사용할 수 있는지 알고 싶다면 __schema 쿼리 실행
루트 타입, 커스텀 타입, 스칼라 타입까지 나옴
query {
__schema {
types {
name
description
}
}
}
특정 타입에 관한 세부 사항만 보고 싶다면 __type 쿼리에 타입명을 인자로 넘기면 된다.
query {
__type(name:"Lift"){
name
fields{
name
description
type{
name
}
}
}
}
GraphQL API를 처음 사용할 때는 아래 쿼리를 통해 루트 타입에서 사용할 수 있는 필드가 무엇이 있는지 알아 보는 편이 좋음
query roots { __schema { queryType { ...typeFields } mutationType { ...typeFields } subscriptionType { ...typeFields } } } fragment typeFields on __Type { name fields { name } }
인트로스펙션 쿼리문은 GraphQL 쿼리 언어의 규칙을 따름
따라서 프래그먼트를 사용하여 쿼리문 안의 중복되는 부분을 없앨 수 있음
GraphQL API로 쿼리를 보낼 때, 문자열은 추상 구문 트리(abstract syntax tree) 로 파싱되어 명령 실행 전에 유효성 검사를 거침
쿼리에는 최소한 정의(definition)가 하나 이상 들어감, 여러개의 정의가 리스트로 들어 있을 수도 있음
정의는 두 타입으로 나뉘어 짐
1. OperationDefinition - mutation, query, subscription
- 각 작업 정의에는 OperationType과 SelectionSet가 들어감
- FragmentDefinition