GraphQL
Facebook에서 처음으로 개발했고, Graph + Query Language의 줄임말로 Server API 를 통해 정보를 주고받기 위해 사용하는 Query Language를 의미한다.
GraphQL은 클라이언트 요청에 따라 유연하게 트리 구조의 JSON 데이터를 응답으로 전송할 수 있다. REST API 방식의 고정된 자원이 아닌 클라이언트 요청에 따라 유연하게 자원을 가져올 수 있다는 점에서 엄청난 이점을 갖기 때문에 사용한다.
Query: 저장된 데이터 가져오기
Mutation: 저장된 데이터 수정하기
Create: 새로운 데이터 생성
Update: 기존의 데이터 수정
Delete: 기존의 데이터 삭제
Subscription: 특정 이벤트가 발생 시 서버가 대응하는 데이터를 실시간으로 클라이언트에게 전송
1. field
//실행
{
hero {
name
# 이런 식으로 GraphQL 내에서 주석도 작성할 수 있다.
friends {
name
}
}
}
//결과
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
2. 전달인자(Arguments)
필드에 인수를 전달하는 부분을 추가하면 원하는 데이터만 받아올 수 있다.
{//id가 1000인 human의 name과 height를 쿼리
human(id: "1000") {
name
height
}
}
//쿼리 결과
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
3. 별명(Aliases)
필드 이름을 중복해서 사용할 수 없으므로, 필드 이름을 중복으로 사용해야 할 때는 별명을 붙여서 쿼리를 해준다.
//이런식으로 hero필드 앞에 별명을 붙여준다.
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
//쿼리 결과
{
"data": {
"empireHero": {
"name": "Luke Skywalker"
},
"jediHero": {
"name": "R2-D2"
}
}
}
4. 오퍼레이션 네임
여태 쿼리와 쿼리 네임을 모두 생략하는 축약형 구문을 사용했지만, 실제 앱에서는 코드를 모호하지 않게 작성하는 것이 중요하다. query는 오퍼레이션 타입으로, query 뿐만 아니라 mutation, subscription, describes 등이 있다. 쿼리를 약식으로 작성하지 않는 한 이런 오퍼레이션 타입은 반드시 필요하다.
//이런식으로 query keyword와 query name을 작성한다.
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
5. 변수(Variables)
실제 앱을 사용할 때는 고정된 인수를 받는 것보다 동적으로 인수를 받아 쿼리하는 경우가 대다수이다. 변수는 그런 인수들을 동적으로 받고 싶을 때 사용한다.
//변수를 사용한 쿼리 예시
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
저장된 데이터 수정하기 GraphQL은 mutation이라는 키워드를 사용하여 서버 측 데이터를 수정한다.
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
스키마의 가장 기본적인 구성 요소는 서비스에서 가져올 수 있는 객체의 종류, 그리고 포함하는 필드를 나타내는 객체 유형이다.
type Character {
name: String!
appearsIn: [Episode!]!
}
위와 같이 스키마를 정의하면 그 스키마 필드에 사용되는 함수의 실제 행동을 Resolver에서 정의한다. 또한 이러한 함수들이 모여 있기 때문에 보통 Resolvers라 부른다.
//GraphQL에서는 데이터를 가져오는 구체적인 과정을 직접 구현해야 하는데
이와 같은 작업(e.g. 데이터베이스 쿼리, 원격 API 요청)을 Resolver가 담당하게 됩니다.
const db = require("./../db")
const resolvers = {
Query: { // **Query :** 저장된 데이터 가져오기 (REST 에 GET 과 비슷합니다.)
getUser: async (_, { email, pw }) => {
db.findOne({
where: { email, pw }
}) ... // 실제 디비에서 데이터를 가져오는 로직을 작성합니다.
...
}
},
Mutation: { // **Mutation :** 저장된 데이터 수정하기 ( Create , Update , Delete )
createUser: async (_, { email, pw, name }) => {
...
}
}
Subscription: { // **Subscription :** 실시간 업데이트
newUser: async () => {
...
}
}
};