항해99에서 프로젝트를 여러번 진행하면서 느낀 점은, 프론트에서 가능하다면 필수적으로 가짜 서버를 도입해야만 한다는 것이다.
미니 프로젝트, 클론코딩, 실전 프로젝트까지 백엔드와 협업을 한 프로젝트는 총 3번이다.
프로젝트 기간은 매번 정해져있는데, 그 프로젝트 기간 안에서 프론트가 api 관련 개발을 백엔드 개발 속도에 의존하게 된다는 점이 매우 불편했다.
미니 프로젝트 작업했을때 백엔드도 프론트와 첫 협업이었기 때문에 서버 배포 속도가 많이 늦었다,,
서버가 거의 발표 전날 배포를 해서, 이를 미리 걱정한 팀원분이 프로젝트 초반에 설정해놓은 json-server가 없었다면 아주 큰일 났을 것이라는 생각이 들었다.
미니 프로젝트 프론트 깃헙 바로가기
이번 실전 프로젝트에서 rest API 관련 개발을 담당하고 있는데, 디자인도 기다려야 하고, 서버 배포도 기다려야 하다보니 초반에 정말 할 일이 없었다 ㄷㄷ
시간이 흐를수록 내가 개발할 수 있는 기간은 줄어드니,, 초조해진 나머지 json-server 도입을 결정했다.
명세서도 이미 있고, 이전 프로젝트에서 팀원분이 json-server를 만들었던 소스도 있고, web socket 강의를 들으며 express 개발도 해봤으니 크게 어렵지 않을 것 같았다!
하지만 명세서가 수정되지 않으리란 보장이 없으니 계속해서 동기화해줘야 한다는 점!! 그래도 서버 배포 후에도 서버가 다시 내려가지 않으리란 보장이 없으니 json-server는 정말 유용하다. ㅎㅎ
인증 요청을 처리할 파일을 만들어주고, 서버 파일도 만들어준다.
파일 이름은 각각 authenticationHandler, index로 했다.
소스에서 본대로 한다 ㅎ
인증 요청을 처리하는 파일은 다음과 같이 작성했다.
// authenticationHandler.js
// 헤더로 받은 authorization을 분리해준다.
const validAuthentication = (req, res) => {
const authorization = req.headers.authorization;
// json-server에서 토큰까지 발급할 필요는 없으니 토큰은 대충 token1, token2 <- 이런식으로
발급했다. 토큰이 없을 경우 에러 핸들링을 해준다.
if (authorization.split(' ')[1][0] !== 't') {
return res.status(401).send({ errorMessage: '회원 인증에 실패했습니다.' });
}
// 토큰이 있을 경우 json-server의 id와 userId를 동일하게 입력해놨으니 숫자만 떼어놓는다!
return authorization.split(' ')[1][5];
};
module.exports = {
validAuthentication,
};
// index.js
const express = require('express');
const jsonServer = require('json-server');
const { validAuthentication } = require('./authenticationHandler');
const fs = require('fs');
const server = jsonServer.create();
const router = jsonServer.router('./db.json');
const middlewares = jsonServer.defaults();
const port = 3001;
server.use(middlewares);
server.use(
jsonServer.rewriter({
'/api/users/me': '/me',
'/api/users/me/keyword': '/me/keyword',
'/api/users/logout': '/logout',
'/api/admin/report': '/report',
}),
);
// 카카오 소셜 로그인
server.get('/api/users/login/kakao', (req, res) => {
res.redirect('http://localhost:3000/login?token=token1');
});
// 닉네임 중복검사
server.get(`/api/users/:nickname`, (req, res) => {
const { nickname } = req.params;
const isNicknameExists = router.db.__wrapped__.me.some((user)
=> user.nickname === nickname);
if (isNicknameExists) {
return res.status(412).send({ result: false,
errorMessage: '이미 사용중인 닉네임입니다.' });
}
return res.status(200).send({ result: true, message: '사용가능한 닉네임입니다.' });
});
// 내 프로필 조회
server.get('/me', (req, res) => {
const authenticatedUserId = validAuthentication(req, res);
const userData = router.db.__wrapped__.me.find((user)
=> user.userId == authenticatedUserId);
const result = {
data: userData,
};
res.jsonp(result);
if (result.data.isFirstLogin) {
const newData = router.db.__wrapped__;
newData.me.map((user) => {
if (user.userId == authenticatedUserId) {
user.isFirstLogin = false;
}
});
fs.writeFileSync('./db.json', JSON.stringify(newData));
}
return;
});
// 회원 키워드 조회
server.get('/me/keyword', (req, res) => {
const authenticatedUserId = validAuthentication(req, res);
const result = {
data: router.db.__wrapped__.keyword.find((user)
=> user.userId == authenticatedUserId),
};
return res.jsonp(result);
});
server.use(express.json());
// 회원정보 수정
server.patch('/me', (req, res) => {
const authenticatedUserId = validAuthentication(req, res);
const isUserExists = router.db.__wrapped__.me.some((user)
=> user.userId == authenticatedUserId);
if (!isUserExists) {
return res.status(401).send({ result: false,
errorMessage: '해당 유저를 찾을 수 없습니다.' });
}
const result = router.db.__wrapped__;
result.me.map((user) => {
if (user.userId == authenticatedUserId) {
user.nickname = req.body.nickname;
user.profileImg = req.body.profileImg;
}
});
fs.writeFileSync('./db.json', JSON.stringify(result));
return res.status(200).send({ result: true,
message: '사용자 정보 변경에 성공하였습니다.' });
});
// 로그아웃
server.get('/logout', (req, res) => {
return res.status(200).send({ result: true, message: '로그아웃 되었습니다.' });
});
server.use(router);
server.listen(port, () => {
console.log('JSON Server is running');
});
module.exports = server;
// index.js
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('./db.json');
const middlewares = jsonServer.defaults();
const port = 3001;
server.use(middlewares);
server.use(
jsonServer.rewriter({
'/api/users/me': '/me',
'/api/users/me/keyword': '/me/keyword',
'/api/users/logout': '/logout',
'/api/admin/report': '/report',
}),
);
server.use(router);
// 위에서 지정한 포트로 서버를 실행시키면, 콘솔로 자~알 실행된다고 알려주자
server.listen(port, () => {
console.log('JSON Server is running');
});
module.exports = server;
const isNicknameExists = router.db.__wrapped__.me.some((user)
=> user.nickname === nickname);
//index.js
const express = require('express');
const fs = require('fs');
// body 값을 읽도록 해준다!
server.use(express.json());
fs.writeFileSync('./db.json', JSON.stringify(newData));
node server/index.js
"server": "server/index.js",
node server
그래서 어느 프로젝트에서 썼냐규?! => 가치마인드 프론트 깃헙 바로가기
정말 유익한 정보네요^^ 훠훠~