목차

🚀 Express.js 웹 프레임워크

Phaser Baduk Metaverse 프로젝트의 Express.js 웹 프레임워크 구현에 대해 설명합니다.


1. Express.js란 무엇인가요?

Express.jsNode.js를 위한 빠르고 유연한 웹 애플리케이션 프레임워크입니다. 웹 서버를 쉽게 만들 수 있게 해주는 도구라고 생각하시면 됩니다.

주요 특징:


2. 프로젝트 구조 이해하기

Express.js 프로젝트의 기본 구조:


3. 기본 서버 설정

1) 필요한 모듈 불러오기

먼저 필요한 모듈들을 불러옵니다:

const express = require('express');
const path = require('path');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('express-rate-limit');

각 모듈의 역할:

2) Express 앱 생성

const app = express();
const PORT = process.env.PORT || 3000;

설명:

3) 보안 미들웨어 설정

app.use(helmet({
    contentSecurityPolicy: {
        directives: {
            defaultSrc: ["'self'"],
            styleSrc: ["'self'", "'unsafe-inline'"],
            scriptSrc: ["'self'", "'unsafe-inline'"],
            imgSrc: ["'self'", "data:", "https:"],
            connectSrc: ["'self'", "ws:", "wss:"]
        }
    }
}));

이 설정의 목적:

4) CORS 설정

app.use(cors({
    origin: process.env.NODE_ENV === 'production' 
        ? ['https://yourdomain.com'] 
        : ['http://localhost:3000', 'http://localhost:8080'],
    credentials: true
}));

CORS란?

5) 압축 및 요청 제한 설정

// 압축 미들웨어
app.use(compression());
 
// 요청 제한 설정
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15분
    max: 100, // IP당 최대 100개 요청
    message: '너무 많은 요청이 발생했습니다. 잠시 후 다시 시도해주세요.'
});
app.use('/api/', limiter);

설명:

6) 데이터 파싱 설정

// JSON 파싱 미들웨어
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

설명:

7) 정적 파일 서빙 설정

// 정적 파일 서빙
app.use(express.static(path.join(__dirname, 'public'), {
    maxAge: '1d',
    etag: true
}));

설명:

8) 로깅 미들웨어

// 로깅 미들웨어
app.use((req, res, next) => {
    console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
    next();
});

설명:


4. 라우트 설정

1) 라우트 파일 불러오기

// 라우트 설정
app.use('/api/games', require('./routes/games'));
app.use('/api/users', require('./routes/users'));
app.use('/api/statistics', require('./routes/statistics'));

설명:

2) 메인 페이지 라우트

// 메인 페이지
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

설명:


5. 에러 처리

1) 404 에러 처리

// 404 에러 처리
app.use((req, res) => {
    res.status(404).json({ error: '페이지를 찾을 수 없습니다.' });
});

설명:

2) 서버 에러 처리

// 에러 핸들링 미들웨어
app.use((err, req, res, next) => {
    console.error('서버 에러:', err);
    res.status(500).json({ error: '서버 내부 오류가 발생했습니다.' });
});

설명:


6. 게임 라우트 예제

1) 게임 라우트 기본 구조

const express = require('express');
const router = express.Router();
const BadukGameController = require('../controllers/BadukGameController');
const auth = require('../middleware/auth');

설명:

2) 게임 목록 조회

// 게임 목록 조회
router.get('/', async (req, res) => {
    try {
        const games = await BadukGameController.getGameList(req.query);
        res.json({
            success: true,
            data: games,
            total: games.length
        });
    } catch (error) {
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

설명:

3) 새 게임 생성

// 새 게임 생성
router.post('/', auth, async (req, res) => {
    try {
        const { gameType, settings } = req.body;
        const game = await BadukGameController.createGame(req.user.id, gameType, settings);
 
        res.status(201).json({
            success: true,
            data: game
        });
    } catch (error) {
        res.status(400).json({
            success: false,
            error: error.message
        });
    }
});

설명:

4) 특정 게임 조회

// 특정 게임 조회
router.get('/:gameId', async (req, res) => {
    try {
        const game = await BadukGameController.getGame(req.params.gameId);
 
        if (!game) {
            return res.status(404).json({
                success: false,
                error: '게임을 찾을 수 없습니다.'
            });
        }
 
        res.json({
            success: true,
            data: game
        });
    } catch (error) {
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

설명:

5) 게임 참가

// 게임 참가
router.post('/:gameId/join', auth, async (req, res) => {
    try {
        const { gameId } = req.params;
        const { playerName } = req.body;
 
        const result = await BadukGameController.joinGame(gameId, req.user.id, playerName);
 
        res.json({
            success: true,
            data: result
        });
    } catch (error) {
        res.status(400).json({
            success: false,
            error: error.message
        });
    }
});

설명:

6) 게임 이동 기록

// 게임 이동 기록
router.post('/:gameId/move', auth, async (req, res) => {
    try {
        const { gameId } = req.params;
        const { x, y, player } = req.body;
 
        const result = await BadukGameController.makeMove(gameId, req.user.id, x, y, player);
 
        res.json({
            success: true,
            data: result
        });
    } catch (error) {
        res.status(400).json({
            success: false,
            error: error.message
        });
    }
});

설명:


7. 서버 실행

1) 서버 시작

// 서버 시작
app.listen(PORT, () => {
    console.log(`서버가 포트 ${PORT}에서 실행 중입니다.`);
    console.log(`http://localhost:${PORT}에서 접속하세요.`);
});

설명:

2) 모듈 내보내기

module.exports = app;

설명:


8. 실습 예제

1) 간단한 Express 서버 만들기

1단계: 프로젝트 초기화

npm init -y
npm install express

2단계: 기본 서버 파일 생성 (app.js)

const express = require('express');
const app = express();
const PORT = 3000;
 
// JSON 파싱 미들웨어
app.use(express.json());
 
// 간단한 라우트
app.get('/', (req, res) => {
    res.json({ message: '안녕하세요! Express 서버입니다.' });
});
 
app.get('/api/users', (req, res) => {
    res.json([
        { id: 1, name: '김철수' },
        { id: 2, name: '이영희' }
    ]);
});
 
// 서버 시작
app.listen(PORT, () => {
    console.log(`서버가 포트 ${PORT}에서 실행 중입니다.`);
});

3단계: 서버 실행

node app.js

4단계: 테스트


9. 주의사항과 팁

1) 보안 주의사항

2) 성능 최적화

3) 디버깅 팁


10. 다음 단계

Express.js 기본을 배웠다면 다음을 학습해보세요:

추천 학습 순서:

이 페이지는 자동으로 생성되었습니다.