January 08, 2021
REST API
의 경우, /users/
를 GET
해오게 되면 이름 사진 주소 등등 관련된 모든 정보가 넘어오게되어 필요하지 않는부분까지 DB에서 찾아 비효율적인 활동이 일어남.over-fetching
이라고 한다.
클라이언트가 요청한 정보보다 많은 정보를 서버에서 가져오는 상황
REST
요청을 하게되는 상황
under-fetching
이라고 한다.Grpahql
로 해결이 가능하다.Graphql서버
와 통신하고 Graphql서버
는 실제 DB서버
와 통신한다.// GraphQL 언어
// 쿼리의 구조. 딱 이렇게 요청한 속성의 값들만 서버에서 반환함.
{
feed {
comments
likeNumber
}
notifications {
isRead
}
user {
userName
profilePic
}
}
// package.json
{
"name": "movieql",
"version": "1.0.0",
"description": "Movie API with Graphql",
"main": "index.js",
"scripts": {
"start": "babel-node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
// index.js에서 import같은 최신 문법을 사용할 수 있도록
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/node": "^7.12.10",
"@babel/preset-env": "^7.12.11",
// graphql 간단 서버
"graphql-yoga": "^1.18.3",
// node.js에서 fetch API를 사용할 수 있도록
"node-fetch": "^2.6.1"
}
}
// .babelrc
{
"presets": ["@babel/preset-env"]
}
graphql
서버를 만드는 과정이다.graphql playground
라는 화면이 보여진다.GraphQLServer
생성자에는 객체가 인자로 보내진다.
typeDefs
: 클라이언트에서 요청한 Query
나 Mutation
의 타입을 찾는다.
Query
: DB에서 받아오는 모든것
Mutation
: DB에 변경을 주는 모든것
resolvers
: Query
나 Mutation
으로 왔을 때, 돌려주는 값을 계산?해주는 부분이다. 말 그대로 Query에 대한 해결사import {GraphQLServer} from 'graphql-yoga';
import resolvers from './graphql/resolvers';
const server = new GraphQLServer({
typeDefs : "graphql/schema.graphql",
resolvers
})
server.start(() => console.log('Graphql Server Running'));
타입스크립트처럼
Query
나 Mutation
은 하나씩만 존재할 수 있다.schema.graphql
의 쿼리 구조에 맞는 응답을 해주는 부분이다.GraphQLServer
의 인자로 필요한 schema
파일과 resolvers
파일을 만든다schema파일은 클라이언트로부터 오는 Query를 찾는 파일이다.
resolvers파일은 schema에서 찾은 타입의 해결을 맡는다.
schema.graphql
에서 Query
를 생성한다.클라이언트에서 user라는 query가 왔을 때, 반환해주는 값의 타입을 지정해준다.
resolvers
에서 찾은 Query
에 대한 해결을 한다.user Query에서 문자열을 꼭 반환한다고 schema에서 찾았기 떄문에, 그에 맞는 결과물을 리턴해준다.
playground
에서 user Query로 요청을 보내면 resolvers
에서 지정한 값이 반환된다.schema.graphql
에서 User
타입을 반환하는 Query
를 생성한다.타입스크립트와 유사하게, 객체형식일 경우 커스텀 타입을 생성할 수 있다.
users가 아닌 user입니다. 오타가 있네요
resolvers
에서 찾은 Query
에 대한 해결을 한다.user Query는 User타입을 꼭 반환한다 하였으니, resolvers에서도 그에 맞는 객체를 반환해준다.
playground
user Query로 요청을 보낼 때, 반환되는 값이 객체라면 꼭 원하는 속성을 함께 보내주어야 한다.
resolvers에서 클라이언트가 요청한 속성들만 보내주는것을 확인할 수 있다.
playground
의 장점schema에서 어떤 타입이 있고, 각 속성들이 어떠한 타입을 요구하는지 확인할 수 있다.
실제 DB를 연동한 것과 같이, 다수의 데이터를 관리해보자.
schema.graphql
에서 Query
를 생성한다.이전과 다르게 두개의 Query를 가지고있다. 잘 보면, 타입스크립트와 매우 유사하다는것을 알 수 있다.
users : User타입의 객체가 담긴 배열을 반환하는 Query
user(id : Int) : Query에 보내어진 인자에 맞는 User타입의 객체 반환
resolvers
에서 찾은 Query
에 대한 해결을 한다.위의 배열이 DB데이터라고 생각하자
users : 해당 DB를 그대로 반환하는것
user(id : Int) : Query에 보내어진 id와 동일한 객체만 반환
playground
모든 유저정보가 담긴 배열의 DB더라도, 필요한 속성만을 지정해서 받을 수 있다.
Query를 보낼 떄, 인자를 같이 보내어서 조건에 맞는 데이터만 찾을 수 있다.
playground
의 장점schema에서 어떤 타입이 있고, 각 속성들이 어떠한 타입을 요구하는지 확인할 수 있다.
schema.graphql
에서 Query
와 Mutation
을 생성한다.Query는 같지만 Mutation이라는 타입이 추가되었다.
Query는 DB에서 가져오는거라면, Mutation은 DB에 변화를 주는 타입이다.
addMovie(name : String!, score : Int!) : 이름과 점수 인자를 보내 영화를 DB에 추가하는 Mutation이다.
deleteMovie(id : Int!) : 해당 id의 영화를 DB에서 제거하는 Mutation이다.
resolvers
에서 찾은 Query
와 Mutation
에 대한 해결을 한다.Query와 Mutation에 두번째 인자로 Query의 변수들이 넘어가는점을 알아야 한다.
DB와, 각종 로직들이다.
필요한 인자를 Mutation으로 보내서 영화를 추가할 수 있다.
id를 보내어 영화를 제거할 수 있다.
schema.graphql
에서 Query
를 생성한다.해당 API에서 제공하는 속성들 중, 반환하고자하는 속성들만 뽑아서 type을 만들어준다.
movies Query의 인자들은 API에서 queryString으로 데이터의 필터링을 하는 값들이다.
resolvers
에서 찾은 Query
에 대한 해결을 한다.각 변수들을 사용하여 fetch API로 데이터를 받아서 반환한다.
위의 예제들 처럼 클라이언트에서는 받고자 하는 속성들만 받을 수 있다.
이를 통해, 클라이언트는 Graphql서버와 query로 소통하고, Graphql서버가 DB서버와 RESTful API로 소통하는것을 알 수 있다.