https://www.apollographql.com/
GraphQL은 Rest API와 같이 명세,형식일 뿐이다.
GraphQL로 서비스를 만들기 위해서는, 그 형식에 따라 프론트엔드에서 데이터를 요청하고, 백엔드에서 이를 받아 수신하여 작업을 처리할 수 있도록 해주는 소프트웨어가 필요하다.
Apollo는 각각 백엔드 서버, 그리고 React 등의 프론트 웹이나 모바일 앱에서 GraphQL을 사용한 정보교환을 간편하게 구현할 수 있도록 한다.
Apollo Server 를 활용한 백엔드 서버 제작
Apollo Client와 React를 활용한 프론드엔드 웹 제작
extentions에서 Edit csv를 설치하면


위와 같은 csv 파일을 vscode의 우측상단에 Edit csv를 눌러서 아래와 같은 엑셀같은 파일로 확인할 수 있다.

csv안에 있는 데이터들을 활용해서 이를 GraphQL로 주고받는 서버를 만들려고 한다.
$ npm i graphql apollo-server
index.js에 아래와 같은 코드를 작성하고 npm start를 해주면 GraphQL Apollo 서버가 열리는 것을 볼 수 있다.
const database = require('./database');
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Query {
teams: [Team]
}
type Team {
id: Int
manager: String
office: String
extension_number: String
mascot: String
cleaning_duty: String
project: String
}
`;
const resolvers = {
Query: {
teams: () => database.teams,
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
typeDef
GraphQL에서 사용할 데이터들의 구조와 타입을 지정해준 것
Query 루트 타입 : Team이라는 데이터가 어떤 항목들로 구성되어 있는지 선언
type Query { teams: [Team] }
type Query : 이 Team이라는 데이터를 요청할 query에도 어떤 형식으로 요청이 들어가 있는지 선언
Type 살펴보기
type Team { id: Int manager: String office: String extension_number: String mascot: String cleaning_duty: String project: String }
resolver
액션들이 함수형태로 지정const resolvers = { Query: { teams: () => database.teams } }

아래와 같은 데이터를 type과 Query을 설정해준다.
{
id: 'machanical keyboard',
used_by: 'developer',
count: 24,
new_or_used: 'used'
},
// typeDefs 설정
const typeDefs = gql`
type Query {
teams: [Team]
equipments:[Equipment]
}
type Team {
id: Int
manager: String
office: String
extension_number: String
mascot: String
cleaning_duty: String
project: String
}
type Equipment {
id: String
used_by: String
count: Int
new_or_used: String
}
`;
// resolvers 구현
const resolvers = {
Query: {
teams: () => database.teams,
equipments : () => database.equipments
},
};
query를 성공적으로 볼 수 있는 것을 볼 수 있다.

Query: {
//...
team: (parent, args, context, info) => database.teams
.filter((team) => {
return team.id === args.id
})[0],
}
type Query {
...
team(id: Int): Team
}
query {
team(id: 1) {
id
manager
office
extension_number
mascot
cleaning_duty
project
}
}
Query: {
// ...
teams: () => database.teams
.map((team) => {
team.supplies = database.supplies
.filter((supply) => {
return supply.team === team.id
})
return team
}),
}
...
type Team {
id: Int
manager: String
office: String
extension_number: String
mascot: String
cleaning_duty: String
project: String
supplies: [Supply]
}
query를 불러오면 잘 불러와진다.

type Mutation {
deleteEquipment(id: String): Equipment
}
// 삭제 resolver
Mutation: {
deleteEquipment: (parent, args, context, info) => {
const deleted = database.equipments
.filter((equipment) => {
return equipment.id === args.id
})[0]
database.equipments = database.equipments
.filter((equipment) => {
return equipment.id !== args.id
})
return deleted
}
}
잘 삭제되는 것을 볼 수 있다.

type Mutation {
insertEquipment(
id: String,
used_by: String,
count: Int,
new_or_used: String
): Equipment
...
}
...
//resolver
Mutation: {
insertEquipment: (parent, args, context, info) => {
database.equipments.push(args)
return args
},
//...
}
잘 추가되는 것을 볼 수 있다.

type Mutation {
editEquipment(
id: String,
used_by: String,
count: Int,
new_or_used: String
): Equipment
...
}
...
//resolver
Mutation: {
// ...
editEquipment: (parent, args, context, info) => {
return database.equipments.filter((equipment) => {
return equipment.id === args.id
}).map((equipment) => {
Object.assign(equipment, args)
return equipment
})[0]
},
// ...
}
잘 수정이 되는 것을 볼 수 있다

- 특정 파일의 코드가 너무 길어지지 않도록 여러 파일에 걸쳐
모듈화해서 작성하려고 한다.apollo-server 생성자 인자 모듈화로 진행하려고 한다.

const { gql } = require('apollo-server')
const dbWorks = require('../dbWorks')
const typeDefs = gql`
type Equipment {
id: String
used_by: String
count: Int
new_or_used: String
}
`
const resolvers = {
Query: {
equipments: (parent, args) => dbWorks.getEquipments(args),
},
Mutation: {
deleteEquipment: (parent, args) => dbWorks.deleteItem('equipments', args),
}
}
module.exports = {
typeDefs: typeDefs,
resolvers: resolvers
}
const { gql } = require('apollo-server');
const typeDefs = gql`
type Mutation {
deleteEquipment(id: String): Equipment
deleteSupply(id: String): Supply
}
`;
module.exports = typeDefs;
const { gql } = require('apollo-server');
const typeDefs = gql`
type Query {
equipments: [Equipment]
supplies: [Supply]
}
`;
module.exports = typeDefs;
const { ApolloServer } = require('apollo-server');
const _ = require('lodash');
const queries = require('./typedefs-resolvers/_queries');
const mutations = require('./typedefs-resolvers/_mutations');
const equipments = require('./typedefs-resolvers/equipments');
const supplies = require('./typedefs-resolvers/supplies');
const typeDefs = [queries, mutations, equipments.typeDefs, supplies.typeDefs];
const resolvers = [equipments.resolvers, supplies.resolvers];
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});