업데이트가 너무 늦어졌다. 하하..
하지만 앞으로 업데이트할 포스팅들이 산더미라는거.. 🏃♀️🏃♀️🏃♀️
npm init -y
(y를 하면 모두 yes를 하는 것)npm install --save-dev graphpack
설치하기"scripts": {
"dev": "graphpack",
"build": "graphpack build"
}
schema.graphql
, resolvers.js
, db.js
파일 만들기type Query {
hello: String
}
import { users } from "./db";
const resolvers = {
Query: {
hello: () => "Hello World!"
}
};
export default resolvers;
export let users = [
{ id: 1, name: "Graph QL", email: "gql@gmail.com" },
{ id: 2, name: "Doori Kim", email: "doori.alice.kim@gmail.com" },
];
npm run dev
명령어 치면 인제 4000 포트에서 서버를 켤 수 있다!gql은 스키마 작성에 사용되는 언어 타입을 가지고 있는데, 이걸 human-readable schema syntax 다시말해 SDL(Schema Definition Language)이라고 한다. 혹시 machine-readable도 있나 찾아봤는데 있다..! 와우
어찌됐든 그래프큐엘은 SDL이라서 내가 어떤 언어나 프레임워크를 쓰든간에 상관이 없다고 한다! 다른 스키마 언어랑은 다르게 보이는 대로 이해하면 된다고 한다..!
Types는 gql에서 가장 중요한 특징 중에 하나이다. 타입들은 API가 어떻게 생겼는지 보여주는 custom object이다. 예를 들어.. 블로그앱을 만든다고 생각하면 포스트, 유저, 좋아요 등의 API가 있을거다.
이러한 타입들은 field를 가지고 있고, 특정한 데이터 타입을 리턴한다.
예를 들어 유저 타입을 만든다고 했을때, 우리는 이름, 이메일, 나이 등의 field를 만든다.
아까 위에서 만든 schema.graphql
파일로 가서 아래의 코드로 대체해주자!
type User {
id: ID!
name: String!
email: String!
age: Int
}
위에서 느낌표는 field가 null이 될 수 없음을 의미한다. 뒤에다 느낌표를 붙인 애들은 쿼리에서 특정 데이터를 꼭 리턴해야 한다. 위의 타입을 살펴봤을때 age만 null을 리턴할 수 있다.
타입은 아래와 같이 정의할 수 있다
(일반적으로 Object. Query, Mutation, Scalar 타입을 많이 쓴다)
👉Scalar - 단일 값을 저장합니다.
👉Object - 데이터의 객체 구조를 보여준다
👉Query - 특정 타입들의 entry point 역할
👉Mutation - 데이터를 조작하는 entry point 역할
👉Enum - 열거형 타입. 목록 중에 선택해야 하는 상황에서 사용
👉List - []를 사용해서 정의할 수 있다
👉Non-Nullable - 정의된 타입 뒤에!
를 붙여서 표현한다. null이 될 수 없으므로 무조건 값을 리턴해줘야 한다.
true
or false
ID를 정의하는 것은 개발자가 읽도록 하는 의도가 아니라 객체를 다시 요청하거나 캐시의 키로써 쓸 때 필요하기 때문!
가 있는데 그건 바로 query
, mutation
, subscribe
이다.
간단하게 살펴보자면...
쿼리는 쉽게 말하자면 데이터를 받는 방식을 말한다. gql의 매력뽀인트는 바로 데이터를 내가 원하는 방식 그대로 받을 수 있다는 것! REST API와 다르게 over-fetching이나 under-fetching의 염려가 없다.
아까 위에서 만든 src폴더 아래에 있는 schema.graphql
에 쿼리라는 타입을 추가해주자.
type Query {
users: [User!]!
}
users 쿼리는 Users 배열을 리턴할텐데, null을 리턴하면 안되서 !을 붙여주었다.
근데 Users 배열 안에서 특정 유저를 불러와야 하기 때문에 아래에 요거 한줄을 덧붙여준다.
user(id: ID!): User!
평소에 메시지 보낼때 느낌표 많이 쓰는 1인으로서 이거 참 이상하다.. 굉장히 강조하는 넉낌
널 리턴하면 안돼!!!!!!!!!! 요런 느낌으로 보인다 ㅋㅋㅋ
여기까지 써도 gql이 어떻게 동작할진 여전히 예상이 가지 않는다.
그래서 resolvers.js
가 존재하는 것..!
아까 헬로 월드 썼던걸 지워주고 아래의 코드 복붙 고고
import { users } from "./db";
const resolvers = {
Query: {
user: (parent, { id }, context, info) => {
return users.find(user => user.id === id);
},
users: (parent, args, context, info) => {
return users;
}
}
};
export default resolvers;
위의 코드를 보면 각각의 쿼리 resolver는 4개의 argument를 갖고 있다.
id를 넘겨주고 특정 유저를 리턴하게 된다. 아주 간단쓰!
아까 서버는 켜놨고.. 쿼리가 잘 들어오나 확인해보자!
로컬 4000에 아래처럼 쿼리를 날려주자!
query {
users {
id
name
email
age
}
}
짠! 요로코롬 잘 호출되고 있따!
특정 유저를 리턴하고 싶다면 id값을 주면 된다.
gql에서 mutation은 내가 서버에 변경된 데이터를 보내거나 업데이트된 데이터를 받는 방식이다. REST에서의 CUD(Create
, Update
, Delete
)를 생각하면 편하다
이제 실습 타임!! schema.graphql
파일로 고고
type Mutation {
createUser(id: ID!, name: String!, email: String!, age: Int): User!
updateUser(id: ID!, name: String, email: String, age: Int): User!
deleteUser(id: ID!): User!
}
백앤드를 잘 몰라서 모르겠는데, 신기하게 함수식에 타입을 다 정의한다
그래프큐엘만의 특징인건가! 모르겠다 ㅋㅋ
이제 resolver.js
로 돌아가서 Query 객체 아래에 Mutation 객체를 만들어준다
Mutation: {
createUser: (parent, { id, name, email, age }, context, info) => {
const newUser = { id, name, email, age };
users.push(newUser);
return newUser;
},
updateUser: (parent, { id, name, email, age }, context, info) => {
let newUser = users.find(user => user.id === id);
newUser.name = name;
newUser.email = email;
newUser.age = age;
return newUser;
},
deleteUser: (parent, { id }, context, info) => {
const userIndex = users.findIndex(user => user.id === id);
if (userIndex === -1) throw new Error("User not found.");
const deletedUsers = users.splice(userIndex, 1);
return deletedUsers[0];
}
}
이제 4000포트로 가서 뮤테이션을 날려보자!
mutation {
createUser(id: 3, name: "삼돌이", email: "samdol@gmail.com", age: 33) {
id
name
email
age
}
}
사실 이 글을 작성하기 전까진 왜 query날릴때 객체 형식인지 몰랐는데
resolvers에 정의된 Query와 Mutation이 모두 객체 형태라서 이렇게 날리는 것이였다 크..
유저 정보가 제대로 들어갔는지 확인해보자.
잘 들어왔다, 최고다!
하지만 subscribe을 해주지 않아서 로컬에 있는 db.js 파일은 동일할 것이다.
일단 이 정도까지만 알아도 백앤드와 통신할 때 무리가 없을 것 같은데
프로젝트 하면서 필요하면 3탄도 나올 예정!
GraphQL에서 진짜 이 정도는 해줘야 내가 필요할 때 mock data를 서버로부터 받아올 수 있어서 좋다.
왜냐... Apollo 공식문서에 있는 codesandbox 링크는 CORS ERROR가 너무 빈번히 일어난다. 도무지 이용할 수가 없다...
급한대로 필요한 양식에 맞춰서 내가 데이터 만들어놓으면
나중에 그거 토대로 불러오면 되는거니까 을매나 좋게요! 😝