Express 설치 및 초기 설정
Express란?
Express는 Node.js를 위한 빠르고 간결한 웹 프레임워크이다. 미들웨어와 라우팅 기능을 제공하여 서버와 API를 쉽게 구축할 수 있게 도와준다.
프로젝트 초기 설정
mkdir express-api
cd express-api
npm init -y
npm install express mongoose cors
npm install --save-dev typescript ts-node @types/node @types/express @types/cors
npx tsc --init
TypeScript 설정
tsconfig.json
파일을 생성하고 다음과 같이 설정한다.
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"]
}
엔드포인트 만들기
엔트리 포인트 설정
프로젝트 구조는 아래와 같다.
express-api
│
├── src
│ ├── routes
│ ├── middleware
│ ├── controllers
│ ├── models
│ ├── app.ts
│ └── index.ts
└── tsconfig.json
src/app.ts
import express, { Application } from 'express';
import cors from 'cors';
import { json, urlencoded } from 'body-parser';
import userRouter from './routes/user';
const app: Application = express();
// 미들웨어 설정
app.use(cors());
app.use(json());
app.use(urlencoded({ extended: true }));
// 정적 파일 제공
app.use(express.static('public'));
// 라우터 설정
app.use('/api/users', userRouter);
export default app;
src/index.ts
import app from './app';
import mongoose from 'mongoose';
const PORT = process.env.PORT || 3000;
const MONGO_URI = process.env.MONGO_URI || 'your_mongodb_connection_string_here';
mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log('MongoDB connected successfully');
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
})
.catch((err) => {
console.error('Failed to connect to MongoDB', err);
});
미들웨어와 use()
미들웨어는 요청(Request)과 응답(Response) 사이에 실행되는 콜백 함수로, 요청을 처리하거나 응답을 수정하는 등의 작업을 수행할 수 있다. 미들웨어는 app.use()
를 통해 설정한다.
const middleware = (req, res, next) => {}
여기서 next는 함수인데 이 함수를 호출하면 모든 것이 정상으로 동작한다. 그러나 next를 호출하지 않으면 이 미들웨어 다음에 메서드 체인으로 연결된 메서드들이 호출되지 않는다.
로깅 미들웨어 추가
import { Request, Response, NextFunction } from 'express';
const logger = (req: Request, res: Response, next: NextFunction) => {
console.log(`url=${req.url}', method=${req.method}`);
next();
};
export default logger;
src/app.ts에 로깅 미들웨어 추가
import logger from './middleware/logger';
app.use(logger);
정적 파일 제공: express.static
express.static이란 이름의 미들웨어를 사용하여 익스프레스 객체가 정적 파일을 제공할 수 있다. 하
src/app.ts에 정적 파일 미들웨어 추가
/public 디렉터리 밑에 파일들을 정적 파일로 제공한다.
app.use(express.static('public'));
JSON 파싱 미들웨어: express.json
클라이언트가 서버로 보내는 JSON 형식의 요청 본문을 파싱 하여 사용할 수 있도록 하는 미들웨어이다.
src/app.ts에 JSON 파싱 미들웨어 추가
app.use(express.json());
CORS 미들웨어
cors 패키지는 서버 응답에 cors 헤더를 설정하거나, 클라이언트가 보내는 프리플라이트 요청에 자동으로 응답하고, 허용할 정책을 관리할 수 있는 기능을 제공한다.
CORS 미들웨어 추가
const express = require('express');
const cors = require('cors');
const app = express();
// CORS 옵션 설정
const corsOptions = {
origin: 'http://example.com', // 허용할 출처
methods: 'GET,POST,PUT,DELETE', // 허용할 메서드
allowedHeaders: 'Content-Type,Authorization', // 허용할 헤더
credentials: true, // 쿠키 등 자격 증명 허용
};
app.use(cors(corsOptions));
라우터 설정
app 객체의 use 메서드에서 사용하는 경로는 절대 경로이지만, 라우터 객체 내부에서 사용하는 경로는 상대 경로이다.
import userRoutes from './routes/user')
app.use('/users', userRoutes);
src/routes/user.ts
import { Router } from 'express';
import { getUser, createUser, updateUser, deleteUser } from '../controllers/userController';
const router: Router = Router();
router.get('/:id', getUser);
router.post('/', createUser);
router.put('/:id', updateUser);
router.delete('/:id', deleteUser);
export default router;
src/controllers/userControllers.ts
import { Request, Response } from 'express';
import User from '../models/user';
export const getUser = async (req: Request, res: Response) => {
try {
const user = await User.findById(req.params.id);
if (!user) return res.status(404).json({ message: 'User not found' });
res.json(user);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
export const createUser = async (req: Request, res: Response) => {
try {
const user = new User(req.body);
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
export const updateUser = async (req: Request, res: Response) => {
try {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!user) return res.status(404).json({ message: 'User not found' });
res.json(user);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
export const deleteUser = async (req: Request, res: Response) => {
try {
const user = await User.findByIdAndDelete(req.params.id);
if (!user) return res.status(404).json({ message: 'User not found' });
res.json({ message: 'User deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
728x90
'Javascript' 카테고리의 다른 글
[JS] ESLint와 TypeScript 설정에서 ES 버전 차이 (0) | 2024.09.01 |
---|---|
[JS] Turborepo를 활용한 공통 라이브러리 관리 (0) | 2024.08.31 |
[JS] 타입스크립트의 Record 타입 (0) | 2024.07.31 |
[JS] peerDepedencies (0) | 2024.07.30 |
순수 함수 (3) | 2024.07.22 |