- RESTAPI 서버에 어떻게 GraphQL을 도입하였는지 기록을 정리하려 합니다.
GraphQL이 무엇인지, 어떻게 쓰는지, 왜 쓰는지 처음으로 접하게 된 글이다.
내 프로젝트는 현재
여기서 GraphQL을 어떻게 적용할 수 있을까..
GraphQL 자바스크립트 공식 Reference Code
npm install express express-graphql graphql
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
var schema = buildSchema(`
type Query {
hello: String
}
`);
var root = { hello: () => 'Hello world!' };
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
공식사이트에서 설명해주는 예제이다.
var schema 를 만들어서 인자로 넣어주고,
app.use('/graphql'~ 사용할 path를 정해주고
graphqlHTTP 객체에 스키마와 옵션을 추가해준다.
위 방식대로 진행하려면,,
모든 DB 테이블에 대하여 각각 타입을 지정해주어야 하는데,
그 볼륨을 생각했을때 디렉토리로 구분해야하고,
쿼리함수와 뮤테이션함수를 각각 또 따로 구현해주어야 하는 상당한 로드가 필수로 발생하므로,
사용할 수 있는 라이브러리가 있는지 혹시 검색해봤다.
아니나 다를까!
sequelize-graphql-schema
시퀄라이즈로 정의한 모델을 바탕으로 자동으로 GraphQLSchema 를 생성해주는 라이브러리가 있었다.
버전은 0.1이지만, 8일전에 업데이트 하였기에 한번 사용해보자.
이용방법은 간단했다.
const { GraphQLSchema } = require('graphql');
const express = require('express');
const graphqlHTTP = require('express-graphql');
var options = {
exclude: ["Users"]
}
const {generateSchema} = require('sequelize-graphql-schema')(options);
const models = require('./models');
const app = express();
app.use(
'/graphql',
graphqlHTTP({
schema: new GraphQLSchema(generateSchema(models)),
graphiql: true
})
)
app.listen(8080, function() {
console.log('RUNNING ON 8080. Graphiql http://localhost:8080/graphql')
})
models 변수에는 내가 정의한 모델 path로 수정해주고
schema 변수에는 해당 라이브러리를 사용하여 새로운 스키마를 생성해서 넣어주기만 하면된다.
바로 적용해서 실행해보았다.
graphiql 을 true로 설정해주었기 때문에
/graphql로 접속시 아래와 같은 UI화면을 바로 확인할 수 있었다.
Ctrl + Space 를 사용하면 자동완성,
Type이나 Query, Mutation에 Spec을 보고 싶으면 우측 상단에 Docs를 보면 된다.
이 라이브러리에서 자동으로 생성해주는 스키마 포맷은 아래와 같다.
Query
[TABLENAME]GET
Mutation
[TABLENAME]Add
[TABLENAME]Edit
[TABLENAME]Delete
각각 DB에 CRUD 역할을 수행하는 네가지 함수이다.
Get - Read
Add - Create
Edit - Update
Delete - Delete
실제 요청은 아래와 같이 보내면 된다.
전체 유저를 보고 싶을 때
query{
userGet{
user_id
}
}
특정 id 유저를 보고 싶을 때
query{
userGet(id : 1){
user_id
}
}
특정 조건에 유저를 보고 싶을 때
query{
userGet(where : {id : {gt : 1}}){
user_id
}
}
query{
userGet(limit : 3, where : {id : {gt : 1}}){
user_id
}
}
query{
userGet(order : "user_id"){
user_id
}
}
query{
userGet(offset : 10){
id, user_id
}
}
유저를 추가할 때
mutation {
userAdd(User : {
user_id : "velog"
}){
id, user_id
}
}
유저를 수정할 때
mutation {
userEdit(User : {
id : 19,
user_id : "velog2"
}){
id, user_id
}
}
유저를 삭제할 때
mutation {
userDelete(id : 19)
}
제대로된 문서가 없어서 알아내기까지 시간이 조금 걸렸다.
혹시 이 포스트를 보는 다른 사람이 있으면 도움이 되었으면 좋겠다. 물론 나도 다시 보러올거지만,,,
후에 Schema를 직접 구현해보면서 느낀건데,
이 라이브러리 만든사람이 대단하다고 느낀다,,
순수하게 mutation을 만드는건 어렵지 않지만
다양한 조건들을 처리해 줄 수 있도록 만드는건...
어우 어렵다.