이번시간에는 GraphQL을 직접 적용시켜보자
GraphQL 만들기 실습
1.실습할 폴더에 GraphQL을 만들 폴더하나 생성
2.package.json 생성 npm init -y
3.npm install --save-dev graphpack 설치하기
4.package.json 아래에 script요소 추가하기
"scripts": {
"dev": "graphpack",
"build": "graphpack build"
}
5.src 폴더 추가 -> schema.graphql , resolvers.js, db.js 파일 생성
(여기서 주의! resolvers안에 s 안붙이면 에러뜬다)
6.schema.graphql 파일에 아래 코드 입력
type Query {
hello: String
}
7.resolvers.js 파일에 아래 코드 입력
import { users } from "./db";
const resolvers = {
Query: {
hello: () => "Hello World!"
}
};
export default resolvers;
8.db 파일에 아래 코드 입력
export let users = [
{ id: 1, name: "Graph QL", email: "gql@gmail.com" },
{ id: 2, name: "Doori Kim", email: "doori.alice.kim@gmail.com" },
];
9.터미널에 npm run dev 명령어 지면 4000 Port에서 서버가 실행된다.
이런 화면이 뜬다 그럼 성공이야 ~~~
Schema 란 무엇인가 ?
gql은 스키마 작성에 사용되는 언어 타입을 가지고 있어, 이걸 human-radable schema syntax 다시말해서
SDL(Schema Definition Language) 이라고 한다.GraphQL은 SDL 이라 내가 어떤 언어나 프레임워크를 쓰던 간에
상관이 없다고 한다. 다른 스키마 언어랑은 다르게 보이지만 그냥 보이는대로 이해하면 된다.
Types란?
Types는 gql에서 가장 중요한 특징 중 하나이다. 타입들은 API가 어떻게 생겼는지 보여주는 custom Object이다.
예를들어 블로그를 제작 한다면 포스트,유저,좋아요 기능 등의 API가 있을건데.
이러한 타입들을 field 가 가지고 있고, 특정한 데이터 타입을 리턴해준다.
예를 들어 유저 타입을 만드다고 할때 우리는 이름, 이메일, 나이 등을 field로 만든다.
그럼 아까 위에서 만든 schema.graphql 로 가서 아래 코드를 대체해주자.
type User {
id: ID!
name: String!
email: String!
age: Int
}
위에서 ! 느낌표는 field 가 null 이 될수 없다는 것을 의미한다. 뒤에다 느낌표를 붙인 애들은 Query에서 특정 데이터를 꼭 리턴 시켜 줘야한다. 위의 타입을 살펴볼때 age만 null로 리턴할수 있다.
타입은 아래와 같이 정의할 수 있다
(일반적으로 Object. Query, Mutation, Scalar 타입을 많이 쓴다)
👉 Scalar
- 단일 값을 저장합니다.
👉 Object
- 데이터의 객체 구조를 보여준다
👉 Query
- 특정 타입들의 entry point 역할
👉 Mutation
- 데이터를 조작하는 entry point 역할
👉 Enum
- 열거형 타입. 목록 중에 선택해야 하는 상황에서 사용
👉 List
- []를 사용해서 정의할 수 있다
👉Non-Nullable
- 정의된 타입 뒤에 ! 를 붙여서 표현한다. null이 될 수 없으므로 무조건 값을 리턴해줘야 한다.
Scalar types
- Int : 부호가 있는 32비트 정수
- Float: 부호가 있는 부동소수점 값
- String: UTF-8 문자열
- Boolean: True or False를 반환
- ID: IndexNumber처럼 고유한 값의 지표로 쓴다.
ID를 정의할때 개발자가 읽도록 하는 의도가 아닌 객체를 다시 요청하거나 캐시의 키로서 쓸때 필요하기 때문!
Object Type
- 위에서 정의한 User 또한 Obejct 타입.
- id, name, email, age : User type에 정의된 field이다. field의 우측에는 scalar type을 써준다
- String: null이 될수 없는 문자열을 의미한다. 즉, 무조건 값을 리턴 해줘야한다.
GQL에서 3가지 중요 포인트
그것은 바로 query, mutation, subscribe 이다.
간단하게 살펴보면...
- query: 서버로부터 데이터를 받는 방법
- mutation: 서버에 올라간 데이터를 업데이트 하는 것(CREACT, UPDATE, DELETE)
- subscribe: 서버와 실시간으로 연결을 유지하는 방법
Query
쿼리를 쉽게 말하면 데이터를 받는 방식이라 할 수 있다. gql에 매력은 바로 데이터를 내가 원하는 방식 그대로 받을 수 있다는 것.
REST API같이 Method를 정해진 것으로 받는 거와는 반대로 over-fecthing 이나 under-fatching의 염려가 없다는 것
아까 위에서 만든 src 폴더 아래 schema.graphql에 쿼리라는 타입을 추가한다.
type Query {
users: [User!]!
}
user 쿼리는 Users 배열을 리턴할텐데, null을 리턴하면 안되기 때문에 !을 붙여준다.
그런데 Users 배열 안에서 특정유저를 불러와야하기 때문에 아래에 추가
user(id: ID!): User!
여기까지 쓰면 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;
아까 Hello World를 지워주고 위 코드를 입력
위 코드를 보면 각각 쿼리 resolver는 4개의 argument를 가지고 있다.
id를 넘겨주고 특정 유저를 리턴하게 된다.
아까 서버를 켜놓았고, 쿼리도 잘드러오고
그럼 localhost: 4000 에 query를 날려주자
잘나온다!!!
특정 유저를 이렇게 리턴하고 싶다 그럼 id 값을 주면 된다.
Mutation
gql 에서 mutaion 은 내가 서버에 변경된 데이터를 보내거나 업데이트 된 데이터를 받는 방식이다.
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!
}
- createUser : 새로운 유저를 등록하는 Mutaiton
- updateUser: 기존 유저를 업데이트 하는 Mutaiton
- deleteUser: ID를 넘겨받고 해당 유저를 삭제하는 Mutation
이제 resolve.js 파일로 가서 Query 객체 아래 Mutaiton 객체를 만들어준다.
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 deleteUsers = users.slice(userIndex, 1);
return deleteUsers[0];
}
}
이제 4000 포트로 이동해서 Mustaion을 날려보자
mutation {
createUser(id: 3, name: "삼돌이", email: "samdol@gmail.com", age: 33) {
id
name
email
age
}
}
잘들어왔다. 굿!
하지만 subscribe를 해주지 않아 로컬에 있는 db.js파일은 동일할 것이다.
일단 이정도 까지만 알아도 백앤드와 통신할 때 무리없을 것이다
참고자료
'프론트 엔드 > React' 카테고리의 다른 글
[REACT 개발 필수]CRA(create-react-app)에 ESLint, Prettier 적용, 설정하는법 (0) | 2021.08.29 |
---|---|
GraphQl 따라잡기 1탄 - GraphQL 개념에 대해 알아보자. (0) | 2021.08.28 |
[Typescript & React & Webpack 환경설정 3편] Webpack 설정을 해보자 (0) | 2021.08.28 |