🌱 폴더 구조
your-project ├── src │ ├── app.js // Express 앱 설정, 미들웨어 및 라우터 연결 │ ├── index.js // 서버의 엔트리 포인트, 서버 실행 코드 포함 │ ├── config │ │ └── db.js // MongoDB 연결 설정 │ ├── models // 데이터베이스 스키마 및 모델 폴더 │ │ └── Post.js // 예시 Mongoose 스키마 및 모델 파일 │ └── routes // API 라우터 폴더 │ └── postsRouter.js // "/api/posts" 라우트를 처리하는 라우터 파일 ├── .env // 환경 변수 파일 ├── package.json // 프로젝트 설정 및 종속성 파일 ├── nodemon.json // Nodemon 설정 파일 └── babel.config.json // Babel 설정 파일
새로운 API 만들기
Express 설치 및 기본 설정
npm init -y
npm install express
// package.json 설정
"start": "node src/index.js" // Scripts 추가
"type": "module" // Type 설정
.env 파일 설정 (환경 변수 사용)
PORT=8080
MONGO_URI=your_mongodb_url
주요 패키지 설치
npm install express mongoose dotenv
npm install --save-dev nodemon @babel/core @babel/node @babel/preset-env
dotenv
: 환경 변수 관리mongoose
: MongoDB와의 연결 및 스키마 관리nodemon
: 서버 자동 재시작@babel
: ES6+ 코드 지원설정 파일 작성
babel.config.json
{
"presets": ["@babel/preset-env"]
}
nodemon.json
{
"watch": ["src/*"],
"ext": "js ts json",
"exec": "babel-node ./src/index.js",
"verbose": true,
"ignore": ["*.test.js", "node_modules"],
"delay": 1500,
"env": {
"NODE_ENV": "development",
"PORT": 8080
}
}
파일별 기본 코드
index.js
import app from './app.js';
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
app.js
import express from 'express';
import dotenv from 'dotenv';
import usersRouter from './routes/usersRouter.js';
dotenv.config();
const app = express();
app.use(express.json()); // JSON 요청 본문 파싱
app.use('/api/users', usersRouter);
// 에러 핸들링 미들웨어
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send({ message: 'Something broke!' });
});
export default app;
db.js
import mongoose from 'mongoose';
import dotenv from 'dotenv';
dotenv.config();
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
const database = mongoose.connection;
database.on('error', (err) => console.log('Database Error!', err));
database.once('open', () => console.log('DB connected'));
routes/usersRouter.js
import { Router } from 'express';
const usersRouter = Router();
usersRouter.get('/', (req, res) => res.send('get all users'));
usersRouter.post('/', (req, res) => res.send('create user'));
usersRouter.put('/:id', (req, res) => res.send('edit user'));
usersRouter.delete('/:id', (req, res) => res.send('delete user'));
export default usersRouter;
models/schema.js
import mongoose, { Schema } from 'mongoose';
const PostSchema = new Schema(
{
title: { type: String, required: true },
content: { type: String, required: true }
},
{ timestamps: true }
);
const Post = mongoose.model('Post', PostSchema);
export default Post;
Request Handler
🌱 요청을 처리하는 콜백 함수
req
req.params
: Path Parameter에 접근할 수 있는 프로퍼티req.queries
: Query String에 접근할 수 있는 프로퍼티req.body
: POST, PUT 요청에 Body에 접근할 수 있는 프로퍼티req.get()
: 요청의 HTTP Header 값을 조회할 수 있는 프로퍼티/api/users/:id // -> Path Parmeter: req.params.id
/api/posts?page=2&size=10 // -> req.queries: req.query.page, req.query.size
/req.get('Authorization') // -> req.get()
res
res.send()
: text 형식의 HTTP 응답 전송res.json()
: JSON 형식의 HTTP 응답 전송res.render()
: HTML Template을 사용하여 화면을 전송res.set()
: 응답의 HTTP Header를 전송res.status()
: 응답의 HTTP Status Code를 설정res.stauts(404).send('User not found');
CRUD 예시
Create
usersRouter.post('/', async (req, res) => {
const { title, content } = req.body;
try {
await Post.create({ title, content });
res.send('Post Successfully Created');
} catch (err) {
console.error(`Error creating post: ${err.message}`);
res.status(500).send('Server Error');
}
});
Read
usersRouter.get('/', async (req, res) => {
try {
const allPosts = await Post.find({});
res.json(allPosts);
} catch (err) {
console.error(`Error Reading post: ${err.message}`);
res.status(500).send('Server Error');
}
});
Update
usersRouter.put('/:id', async (req, res) => {
const { id } = req.params;
const { title, content } = req.body;
try {
const updatedPost = await Post.findByIdAndUpdate(id, { title, content }, { new: true });
if (!updatedPost) return res.status(404).send('Post not found');
res.json(updatedPost);
} catch (err) {
console.error(`Error Updating post: ${err.message}`);
res.status(500).send('Server Error');
}
});
Delete
usersRouter.delete('/:id', async (req, res) => {
const { id } = req.params;
try {
const deletedPost = await Post.findByIdAndDelete(id);
if (!deletedPost) return res.status(404).send('Post not found');
res.json(deletedPost);
} catch (err) {
console.error(`Error Deleting post: ${err.message}`);
res.status(500).send('Server Error');
}
});