REST API 서버 구축 단계별 튜토리얼 – 완성까지 한번에!

REST API 서버 구축 단계별 튜토리얼 – 완성까지 한번에!

프로젝트 소개 및 목표

REST API 서버 구축 단계별 튜토리얼은 Node.js와 Express를 활용하여 실무에서 사용 가능한 RESTful API 서버를 처음부터 끝까지 구축하는 과정을 안내합니다. 이 튜토리얼을 통해 사용자 인증, 데이터베이스 연동, CRUD 작업, 에러 핸들링, 보안 설정까지 모든 핵심 개념을 실습하며 배울 수 있습니다. 백엔드 개발의 기초를 다지고 싶은 주니어 개발자나 포트폴리오를 강화하고 싶은 개발자에게 최적화된 가이드입니다. 완성된 프로젝트는 실제 서비스의 백엔드 기반으로 활용할 수 있으며, 추가 기능 확장도 용이합니다.

필요한 기술 스택

이 프로젝트를 진행하기 위해 다음 기술들이 필요합니다:

  • Node.js (v16 이상): JavaScript 런타임 환경
  • Express.js: 웹 프레임워크
  • MongoDB: NoSQL 데이터베이스 (또는 PostgreSQL)
  • Mongoose: MongoDB ODM
  • JWT: 사용자 인증을 위한 토큰 기반 인증
  • Postman: API 테스트 도구
  • dotenv: 환경 변수 관리

프로젝트 셋업

먼저 프로젝트 디렉토리를 생성하고 필요한 패키지들을 설치합니다. 터미널에서 다음 명령어를 순서대로 실행하세요:

mkdir rest-api-tutorial
cd rest-api-tutorial
npm init -y
npm install express mongoose dotenv bcryptjs jsonwebtoken cors helmet
npm install --save-dev nodemon

package.json 파일을 열어 scripts 섹션을 다음과 같이 수정합니다:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  }
}

프로젝트 루트에 .env 파일을 생성하고 환경 변수를 설정합니다:

PORT=5000
MONGODB_URI=mongodb://localhost:27017/restapi
JWT_SECRET=your_jwt_secret_key_here

단계별 구현 과정

1단계: 기본 서버 설정

server.js 파일을 생성하고 Express 서버의 기본 구조를 작성합니다:

const express = require('express');
const dotenv = require('dotenv');
const cors = require('cors');
const helmet = require('helmet');

dotenv.config();

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

// 미들웨어 설정
app.use(helmet()); // 보안 헤더 설정
app.use(cors()); // CORS 허용
app.use(express.json()); // JSON 파싱
app.use(express.urlencoded({ extended: true }));

// 기본 라우트
app.get('/', (req, res) => {
  res.json({ message: 'REST API 서버가 정상 작동중입니다!' });
});

app.listen(PORT, () => {
  console.log(`서버가 포트 ${PORT}에서 실행중입니다.`);
});

2단계: 데이터베이스 연결

config 폴더를 생성하고 database.js 파일에 MongoDB 연결 로직을 작성합니다:

const mongoose = require('mongoose');

const connectDB = async () => {
  try {
    await mongoose.connect(process.env.MONGODB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    console.log('MongoDB 연결 성공');
  } catch (error) {
    console.error('MongoDB 연결 실패:', error.message);
    process.exit(1);
  }
};

module.exports = connectDB;

server.js에 데이터베이스 연결을 추가합니다:

const connectDB = require('./config/database');

// 데이터베이스 연결
connectDB();

3단계: 사용자 모델 생성

models 폴더를 생성하고 User.js 파일에 사용자 스키마를 정의합니다:

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: [true, '사용자명을 입력해주세요'],
    unique: true,
    trim: true,
    minlength: 3
  },
  email: {
    type: String,
    required: [true, '이메일을 입력해주세요'],
    unique: true,
    lowercase: true,
    match: [/^\S+@\S+\.\S+$/, '유효한 이메일을 입력해주세요']
  },
  password: {
    type: String,
    required: [true, '비밀번호를 입력해주세요'],
    minlength: 6,
    select: false
  },
  role: {
    type: String,
    enum: ['user', 'admin'],
    default: 'user'
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
});

// 비밀번호 해싱 미들웨어
userSchema.pre('save', async function(next) {
  if (!this.isModified('password')) return next();
  this.password = await bcrypt.hash(this.password, 12);
  next();
});

// 비밀번호 검증 메서드
userSchema.methods.comparePassword = async function(candidatePassword) {
  return await bcrypt.compare(candidatePassword, this.password);
};

module.exports = mongoose.model('User', userSchema);

4단계: 인증 미들웨어 구현

middleware 폴더에 auth.js 파일을 생성하고 JWT 인증 로직을 작성합니다:

const jwt = require('jsonwebtoken');
const User = require('../models/User');

exports.protect = async (req, res, next) => {
  try {
    let token;
    
    if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
      token = req.headers.authorization.split(' ')[1];
    }

    if (!token) {
      return res.status(401).json({ message: '인증 토큰이 필요합니다' });
    }

    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = await User.findById(decoded.id);
    
    next();
  } catch (error) {
    res.status(401).json({ message: '유효하지 않은 토큰입니다' });
  }
};

exports.authorize = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ message: '접근 권한이 없습니다' });
    }
    next();
  };
};

5단계: 인증 컨트롤러 작성

controllers 폴더에 authController.js를 생성합니다:

const jwt = require('jsonwebtoken');
const User = require('../models/User');

const signToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, {
    expiresIn: '7d'
  });
};

exports.register = async (req, res) => {
  try {
    const { username, email, password } = req.body;

    const userExists = await User.findOne({ $or: [{ email }, { username }] });
    if (userExists) {
      return res.status(400).json({ message: '이미 존재하는 사용자입니다' });
    }

    const user = await User.create({ username, email, password });
    const token = signToken(user._id);

    res.status(201).json({
      success: true,
      token,
      user: {
        id: user._id,
        username: user.username,
        email: user.email,
        role: user.role
      }
    });
  } catch (error) {
    res.status(500).json({ message: '서버 오류가 발생했습니다', error: error.message });
  }
};

exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    if (!email || !password) {
      return res.status(400).json({ message: '이메일과 비밀번호를 입력해주세요' });
    }

    const user = await User.findOne({ email }).select('+password');
    if (!user || !(await user.comparePassword(password))) {
      return res.status(401).json({ message: '이메일 또는 비밀번호가 올바르지 않습니다' });
    }

    const token = signToken(user._id);

    res.json({
      success: true,
      token,
      user: {
        id: user._id,
        username: user.username,
        email: user.email,
        role: user.role
      }
    });
  } catch (error) {
    res.status(500).json({ message: '서버 오류가 발생했습니다', error: error.message });
  }
};

6단계: 라우트 설정

routes 폴더에 authRoutes.js를 생성하고 인증 관련 라우트를 정의합니다:

const express = require('express');
const { register, login } = require('../controllers/authController');
const router = express.Router();

router.post('/register', register);
router.post('/login', login);

module.exports = router;

server.js에 라우트를 연결합니다:

const authRoutes = require('./routes/authRoutes');

app.use('/api/auth', authRoutes);

7단계: 에러 핸들링 미들웨어

middleware 폴더에 errorHandler.js를 생성합니다:

const errorHandler = (err, req, res, next) => {
  console.error(err.stack);

  res.status(err.statusCode || 500).json({
    success: false,
    message: err.message || '서버 오류가 발생했습니다',
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
  });
};

module.exports = errorHandler;

server.js의 라우트 설정 후에 추가합니다:

const errorHandler = require('./middleware/errorHandler');

app.use(errorHandler);

테스트 및 배포

API 테스트

Postman을 사용하여 API 엔드포인트를 테스트합니다. 다음 요청들을 순서대로 테스트하세요:

  1. 회원가입: POST http://localhost:5000/api/auth/register
{
  "username": "testuser",
  "email": "[email protected]",
  "password": "password123"
}
  1. 로그인: POST http://localhost:5000/api/auth/login
{
  "email": "[email protected]",
  "password": "password123"
}

배포 준비

프로덕션 환경을 위한 설정을 추가합니다. .gitignore 파일을 생성하여 민감한 정보를 제외합니다:

node_modules/
.env
*.log

Heroku, AWS, DigitalOcean 등의 플랫폼에 배포할 수 있습니다. MongoDB Atlas를 사용하면 클라우드 데이터베이스를 쉽게 설정할 수 있습니다.

마무리 및 확장 아이디어

REST API 서버 구축 단계별 튜토리얼을 통해 기본적인 RESTful API 서버를 완성했습니다. 추가로 구현할 수 있는 기능들은 다음과 같습니다: 비밀번호 재설정 기능, 이메일 인증, OAuth 소셜 로그인, 파일 업로드, 페이지네이션, 필터링 및 정렬, Rate Limiting, API 문서화(Swagger), 로깅 시스템, 캐싱(Redis), WebSocket 실시간 통신 등이 있습니다. 이러한 기능들을 단계적으로 추가하며 더욱 완성도 높은 API 서버를 만들어보세요!

📚 함께 읽으면 좋은 글

1

REST API 서버 구축 단계별 튜토리얼 – 완성까지 한번에!

📂 프로젝트 아이디어
📅 2025. 11. 5.
🎯 REST API 서버 구축 단계별 튜토리얼

2

REST API 서버 구축 단계별 튜토리얼 – 완성까지 한번에!

📂 프로젝트 아이디어
📅 2025. 11. 2.
🎯 REST API 서버 구축 단계별 튜토리얼

3

REST API 서버 구축 단계별 튜토리얼 – 완성까지 한번에!

📂 프로젝트 아이디어
📅 2025. 11. 1.
🎯 REST API 서버 구축 단계별 튜토리얼

4

실시간 채팅 앱 만들기 with Socket.io – 완성까지 한번에!

📂 프로젝트 아이디어
📅 2025. 11. 9.
🎯 실시간 채팅 앱 만들기 with Socket.io

5

30분만에 만드는 Todo App 완성 가이드 – 완성까지 한번에!

📂 프로젝트 아이디어
📅 2025. 11. 9.
🎯 30분만에 만드는 Todo App 완성 가이드

💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!

📢 이 글이 도움되셨나요? 공유해주세요!

여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨

🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏

💬 여러분의 소중한 의견을 들려주세요!

REST API 서버 구축 단계별 튜토리얼에 대한 여러분만의 경험이나 노하우가 있으시나요?

💡
유용한 정보 공유

궁금한 점 질문

🤝
경험담 나누기

👍
의견 표현하기

⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨

🔔 블로그 구독하고 최신 글을 받아보세요!

📚
다양한 주제
17개 카테고리

정기 업데이트
하루 3회 발행

🎯
실용적 정보
바로 적용 가능

💡
최신 트렌드
2025년 기준

🌟 프로젝트 아이디어부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨

📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!

답글 남기기