처음 fetch, REST API 같은 애들이 나올 때, 나는 'header... body... 어쩌라는거지?' 이런 생각뿐이었다. 하지만 비슷한 개념을 한번 공부했다고 오늘 GraphQL을 배울 때는 훨씬 수월했다. REST API와는 달리 한 번에 요청을 보낼 수 있는 점이 정말 좋았다.
Chapter1. GraphQL
-1.GraphQL이란
-2.REST API 대신 GraphQL 사용하는 이유
-3.GraphQL로 그래프 순회
-4.GraphQL vs REST API
Chapter2. GraphQL 다루기
-1.GraphQL Keywords
-2.Queries
-3.Mutations
-4.Schema & Type
-5.Resolver
Graph + Query Language
Facebook에서 개발한 오픈 소스로 제공된 쿼리 언어
참고.Query Language란
데이터베이스나 정보 시스템에 query를 보내 데이터를 요청, 검색하는 컴퓨터 프로그래밍 언어
Server API를 통해 정보를 주고받기 위해 사용
-HTTP를 통해 API 서버로 요청을 보내고 응답을 받음
-응답을 JSON 형식으로 받음
-서버 개발자가 작성한 각 필드에 대응하는 resolver 함수로 각 필드의 데이터 조회 가능
-GraphQL 라이브러리가 조회 대상 schema가 유효한지 검사
-REST API와의 차이점
보통 하나의 엔드포인트를 가짐
요청할 때 사용하는 쿼리에 따라 다른 응답을 받을 수 있음
원하는 데이터(response)만 받을 수 있음
즉, GraphQL은 모든 데이터의 형태가 연결되어 있다고 전제하므로 클라이언트 요청에 따라 유연하게 자원을 가져올 수 있음
-Entity(엔티티): 사물의 구조나 상태, 동작 등을 모델로 표현하는 경우, 그 모델의 구성요소
ex. 학생의 entity: 학번, 이름, 학과
출처: https://www.apollographql.com/blog/graphql/basics/the-concepts-of-graphql/
-Overfetch: 필요 없는 데이터까지 제공
ex. user의 name만 필요한 경우에도 id, name, address, birthday를 다 가져옴
{
"user": {
"id": "e43kfhdjsl9"
"name": "Mary"
"address": {...}
"birthday": "July 26, 1982"
}
}
-Underfetch: 하나의 endpoint가 필요한 정보를 충분히 제공하지 못함
ex.user의 name, posts, followers가 필요하다면 3가지 엔드포인트에 요청을 보내야 함
/user/id
/user/id/posts
/user/id/followers
-하나의 endpoint 요청: /graphql
이라는 하나의 endpoint로 요청 -> query , mutation을 resolver 함수로 전달 -> 요청에 응답(모든 클라이언트 요청은 POST 메소드를 사용)
-underfetching, overfetching 없음
-playground라는 GUI를 이용해 resolver 와 schema 를 한눈에 보고 테스트 해 볼 수 있음(POSTMAN과 비슷)
-클라이언트 구조 변경에도 지장이 없음: 데이터를 결정하고 받는 주체가 클라이언트이기 때문에 서버에 지장 없음
-GraphQL를 학습하는 데 시간이 필요
-캐싱이 REST보다 훨씬 복잡함(POST 메소드만을 이용하기 때문에 각 메소드에 따른 캐싱을 지원받을 수 없음 -> Apollo 엔진의 캐싱, 영속 쿼리 등장)
-고정된 요청과 응답만 필요할 경우에는 Query로 인해 요청의 크기가 RESTful API의 경우보다 더 커짐
-Query: 저장된 데이터 가져오기 (REST의 GET과 비슷)
-Mutation: 저장된 데이터 수정하기
Fields / Arguments / Aliases / Operation name / Variables
-Mutation
-Variables
-Response
해당 서비스에서 쿼리 가능한 데이터들의 타입을 정의한 문서
확장자는 .graphql
-Object type: field(O)
-Scalar type: field(X) -> Int, Float, Stirng, Boolean, ID
// Character는 임의의 이름
// Character -> Object type
// name, appearsIn -> Scalar type
type Character {
name: String!
appearsIn: [Episode!]!
}
-Query type
// Schema에서 Query type 정의
schema {
query: Query
mutation: Mutation
}
type Query {
hero(episode: Episode): Character
droid(id: ID!): Droid
}
// query로 데이터 불러 올 때
// Schema에서의 흐름: Query -> hero -> Character -> name
query {
hero {
name
}
}
-Mutation type
type Mutation {
addCharacter(name: String!, appearsIn: [Episode!]!) : Character
}
-> 백엔드가 작성
요청에 대한 응답을 결정해주는 함수.
GraphQL의 여러 가지 타입 중 Query, Mutation, Subscription과 같은 타입의 실제 일하는 방식 즉 로직이 정의됨.
보통 이러한 함수들은 모여 있기 때문에 Resolvers라 부름.
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 () => {
...
}
}
};