다음의 명령어로 디렉토리를 생성하고 gateway를 위한 라이브러리를 설치하도록 하겠습니다.
mkdir api-gateway
cd api-gateway
npm init
mkdir src && touch src/index.js
npm install @apollo/gateway apollo-server-core apollo-server-express cors dotenv express graphql@15.8.0 nodemon winston winston-daily-rotate-file tsc-watch
npm install -D @types/express typescript
우선은 gateway 서버를 작동하기 위한 라이브러리만 설치하고 추후에 인증과 인가에 관한 기능을 작성할 때 관련 라이브러리를 설치하도록 하겠습니다.
PORT=6900
AUTH_SERVICE_ENDPOINT=http://localhost:6000/auth-service
require('dotenv').config();
import { ApolloServer } from 'apollo-server-express';
import { ApolloGateway } from '@apollo/gateway';
import { ApolloServerPluginDrainHttpServer } from 'apollo-server-core';
import express from 'express';
import cors from 'cors';
import http from 'http';
import { Authentication } from './auth/authentication';
const {
PORT,
AUTH_SERVICE_ENDPOINT
} = process.env;
class Server {
constructor() {}
public async start() {
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
gateway: new ApolloGateway({
serviceList: [
{
name: "auth-service",
url: AUTH_SERVICE_ENDPOINT
}
],
buildService: ({
name,
url
}) => {
return new Authentication({ url });
}
}),
context: ({ req }) => {
const token = req.headers.authorization;
if(token) {
return { token };
}
},
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
});
app.use(cors());
await server.start();
server.applyMiddleware({
app,
path: "/",
cors: false
});
httpServer.listen({ port: PORT });
console.log(`🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`);
}
}
const server = async () => await new Server().start();
server();
apollo gateway에서는 serviceList에 subgraph 서버를 등록하여 하나의 gateway를 이용하여 등록된 서비스에 쿼리를 전송할 수 있는 마이크로 서비스의 구조를 사용할 수 있습니다.
이 정도로 gateway 서버를 작성해보았고 테스트를 진행해보도록 하겠습니다.
서비스 인스턴스를 띄우고 난 다음에 gateway인스턴스를 띄우도록 하겠습니다.
메서드 별로 테스트를 진행해보도록 하겠습니다.
1) 회원가입
운전자 데이터 등록
승객 데이터 등록
승객 데이터
{
"_id": {
"$oid": "61ba98b827fb701a2b026e5c"
},
"email": "test-email-001@example.com",
"password": "$2b$10$J6gbgaAwk5jOVFXLvkD8L.JfiaebF97EB2yEskW.ayvSFMd3UHiO2",
"nickname": "test-nickname-001",
"created_at": "2021-12-16T01:39:04.632Z",
"role": "PASSENGER",
"license": null,
"user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
"is_delete": false,
"__v": 0
}
운전자 데이터
{
"_id": {
"$oid": "61ba988827fb701a2b026e59"
},
"email": "test-email-002@example.com",
"password": "$2b$10$Cp2/yVVJ7vzKuZRivz2axeUBY/LagwcTgDmP1RJU5dbPrnJQo.pYi",
"nickname": "test-nickname-002",
"created_at": "2021-12-16T01:38:16.979Z",
"role": "DRIVER",
"license": {
"birth_date": "1990-01-01",
"name": "test-name",
"lic_number": "00-10288100",
"_id": {
"$oid": "61ba988827fb701a2b026e5a"
}
},
"user_id": "cd9f524e-2609-4acc-95f6-abde4df6b479",
"is_delete": false,
"__v": 0
}
회원가입이 잘 진행된 모습을 볼 수 있습니다.
2) 로그인
토큰을 잘 반환합니다.
User not found 에러 메시지를 잘 반환합니다.
Wrong password 에러 메시지를 잘 반환합니다.
3) 유저 불러오기
유저의 정보를 잘 불러오는 모습을 볼 수 있습니다.
4) 닉네임 체크
닉네임 중복 코드를 반환합니다.
고유 닉네임임을 알리는 코드를 반환합니다.
5) 이메일 체크
이메일 중복 코드를 반환합니다.
고유 이메일임을 알리는 코드를 반환합니다.
6) 회원 정보 수정
운전면허등록
비밀번호 수정
닉네임 수정
수정 전 데이터와 수정 후 데이터를 비교해보겠습니다.
{
"_id": {
"$oid": "61ba98b827fb701a2b026e5c"
},
"email": "test-email-001@example.com",
"password": "$2b$10$J6gbgaAwk5jOVFXLvkD8L.JfiaebF97EB2yEskW.ayvSFMd3UHiO2",
"nickname": "test-nickname-001",
"created_at": "2021-12-16T01:39:04.632Z",
"role": "PASSENGER",
"license": null,
"user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
"is_delete": false,
"__v": 0
}
{
"_id": {
"$oid": "61ba98b827fb701a2b026e5c"
},
"email": "test-email-001@example.com",
"password": "$2b$10$mXi4lk6gSrVICX1Ie4U4j.z/B0iWM2TmvdAyP/U8y5kAW6enMB/W.",
"nickname": "modify-nickname-001",
"created_at": "2021-12-16T01:39:04.632Z",
"role": "DRIVER",
"license": {
"birth_date": "1991-01-02",
"name": "test-user-001",
"lic_number": "02-11263671",
"_id": {
"$oid": "61baa7cf87bad08c82f58c99"
}
},
"user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
"is_delete": false,
"__v": 0
}
비밀번호, 닉네임, 운전면허의 데이터가 잘 수정된 모습을 볼 수 있습니다.
7) 유저 삭제
{
"_id": {
"$oid": "61ba98b827fb701a2b026e5c"
},
"email": "test-email-001@example.com",
"password": "$2b$10$mXi4lk6gSrVICX1Ie4U4j.z/B0iWM2TmvdAyP/U8y5kAW6enMB/W.",
"nickname": "modify-nickname-001",
"created_at": "2021-12-16T01:39:04.632Z",
"role": "DRIVER",
"license": {
"birth_date": "1991-01-02",
"name": "test-user-001",
"lic_number": "02-11263671",
"_id": {
"$oid": "61baa7cf87bad08c82f58c99"
}
},
"user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
"is_delete": true,
"__v": 0
}
is_delete: true로 잘 변경되었습니다.
auth-service의 모든 메서드에 대한 테스트를 잘 진행해보았고, 수정한 데이터는 원래대로 되돌리도록 하겠습니다. 다음 포스트에서는 apollo federation에서의 인증과 인가를 적용하는 부분을 알아보도록 하겠습니다.