소개
노드서버를 구성하고 기본 CRUD(Create, Read, Update, Delete) 기능을 직접 코드로 작성하고, 로그인은 JWT(Json Web Token)를 이용한 인증, 로그아웃 기능, 그리고 회원가입 기능도 직접 코드로 작성해주고, 서버의 로깅 라이브러리도 적용해주었습니다.
프로젝트 파일 구성
- controllers : 클라이언트의 요청을 받아들이고, 비즈니스 로직을 수행합니다.
- models : 데이터를 저장하고, 검색하고, 업데이트하고, 삭제합니다.
- routes : 클라이언트의 요청을 controllers에 전달합니다.
- services : 비즈니스 로직을 처리합니다.
- utils : 유틸리티 함수를 포함합니다.
CRUD 기능 추가하기
먼저, 라우팅을 통해 클라이언트의 요청을 받아들이는 API를 작성합니다. API는 HTTP 메서드별로 구분하여 작성합니다.
Create
데이터를 추가하는 API는 POST 메서드로 구현합니다. 클라이언트로부터 전달받은 데이터를 models에서 정의한 스키마에 맞게 생성하고, DB에 저장합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.post('/users', UserController.createUser);
// controllers/user.controller.js
const User = require('../models/user.model');
const createUser = async (req, res) => {
try {
const user = new User(req.body);
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
module.exports = { createUser };
// models/user.model.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true }
});
const User = mongoose.model('User', userSchema);
module.exports = User;
Read
데이터를 조회하는 API는 GET 메서드로 구현합니다. DB에서 데이터를 조회한 후, 클라이언트에게 응답합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.get('/users', UserController.getUsers);
// controllers/user.controller.js
const User = require('../models/user.model');
const getUsers = async (req, res) => {
try {
const users = await User.find();
res.json(users);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { getUsers };
// models/user.model.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true }
});
const User = mongoose.model('User', userSchema);
module.exports = User;
Update
데이터를 수정하는 API는 PUT 메서드로 구현합니다. 클라이언트로부터 전달받은 데이터로 DB에서 데이터를 수정합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.put('/users/:id', UserController.updateUser);
// controllers/user.controller.js
const User = require('../models/user.model');
const updateUser = async (req, res) => {
try {
const { id } = req.params;
await User.findByIdAndUpdate(id, req.body);
res.status(204).end();
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { updateUser };
// models/user.model.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true }
});
const User = mongoose.model('User', userSchema);
module.exports = User;
Delete
데이터를 삭제하는 API는 DELETE 메서드로 구현합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.delete('/users/:id', UserController.deleteUser);
// controllers/user.controller.js
const User = require('../models/user.model');
const deleteUser = async (req, res) => {
try {
const { id } = req.params;
await User.findByIdAndDelete(id);
res.status(204).end();
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { deleteUser };
// models/user.model.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true }
});
const User = mongoose.model('User', userSchema);
module.exports = User;
JWT를 이용한 로그인 및 로그아웃 기능 추가하기
JWT를 이용하여 로그인 및 로그아웃 기능을 구현합니다.
로그인
클라이언트가 로그인 요청을 보내면, 서버는 입력받은 정보를 검증하여 유효한 사용자인지 확인합니다. 유효한 사용자이면, JWT 토큰을 생성하여 클라이언트에게 전달합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.post('/login', UserController.login);
// controllers/user.controller.js
const jwt = require('jsonwebtoken');
const User = require('../models/user.model');
const login = async (req, res) => {
try {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (!user || user.password !== password) {
res.status(401).json({ message: 'Invalid credentials' });
return;
}
const token = jwt.sign(
{ username: user.username },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
res.json({ token });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { login };
로그아웃
클라이언트가 로그아웃 요청을 보내면, 서버는 JWT 토큰을 만료시킵니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.post('/logout', UserController.logout);
// controllers/user.controller.js
const logout = async (req, res) => {
try {
res.status(204).end();
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { logout };
회원가입 기능 추가하기
클라이언트가 회원가입 요청을 보내면, 서버는 입력받은 정보를 검증하여 유효한 정보인지 확인한 후, DB에 저장합니다.
// routes/index.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/user.controller');
router.post('/signup', UserController.signup);
// controllers/user.controller.js
const User = require('../models/user.model');
const signup = async (req, res) => {
try {
const { username, password, email } = req.body;
const user = new User({ username, password, email });
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
module.exports = { signup };
// models/user.model.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true }
});
const User = mongoose.model('User', userSchema);
module.exports = User;
서버의 로깅 라이브러리 적용하기
서버의 로깅을 위해 morgan 라이브러리를 사용합니다. morgan 미들웨어를 추가하여, HTTP 요청과 응답의 정보를 로깅합니다.
// app.js
const express = require('express');
const mongoose = require('mongoose');
const morgan = require('morgan');
const app = express();
const PORT = process.env.PORT || 3000;
mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
});
app.use(express.json());
app.use(morgan('tiny'));
const indexRouter = require('./routes/index');
app.use('/', indexRouter);
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
마무리
이번 글에서는, 노드서버를 구성하고, 기본 CRUD 기능부터 JWT를 이용한 로그인 및 로그아웃, 회원가입 기능까지 구현해보았습니다. 코드의 주요 부분을 한글로 주석처리하여, 이해하기 쉽게 작성하였습니다. 노드의 최신 버전을 사용하고, MVC 패턴으로 controller, service, repository를 구성하였습니다. 서버의 로깅을 위해 morgan 미들웨어를 적용하였습니다. 이를 통해 더욱 실용적인 노드서버를 구성할 수 있습니다.
내저장소 바로가기 luxury515