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에서도 그에 맞는 객체를 반환해준다.
playgrounduser 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로 소통하는것을 알 수 있다.