Node.js · 2025-12-07

Express로 RESTful API 쉽게 구현하기

Express와 Node.js를 이용해 RESTful API를 단계별로 설명한 실무형 참고자료

작성일 : 2025-12-07 ㆍ 작성자 : 관리자
post
목차

개요

이 글은 Express로 RESTful API를 처음부터 구현하는 흐름을 정리한 문서다. 환경 설정부터 라우팅, 미들웨어, 예외 처리, 테스트와 배포까지 핵심을 실무 관점에서 다룬다. 예제는 최소한의 의존성으로 구성해 이해를 돕는다.

사전 준비

Node.js와 npm이 설치되어 있어야 한다. 프로젝트 초기화와 기본 패키지 설치 과정을 소개한다.

프로젝트 초기화

mkdir express-rest-api
cd express-rest-api
npm init -y
npm install express dotenv

위 명령으로 Express와 환경변수 관리를 위한 dotenv를 설치한다.

기본 서버 구성

간단한 서버 구조를 먼저 만든다. express.json()으로 JSON 바디를 파싱한다.

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

app.use(express.json())

app.get('/', (req, res) => {
  res.json({ message: 'API 서버 작동 중' })
})

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`)
})

한 파일로 시작해 기능별로 분리하는 방식으로 확장하면 된다.

라우팅 설계

REST 원칙에 따라 리소스별로 엔드포인트를 설계한다. 예: /users, /posts

라우터 분리

라우터를 모듈화하면 유지보수가 쉬워진다. 예제는 users 라우터 구성이다.

// routes/users.js
const express = require('express')
const router = express.Router()

let users = []

router.get('/', (req, res) => res.json(users))
router.post('/', (req, res) => {
  const user = { id: Date.now(), ...req.body }
  users.push(user)
  res.status(201).json(user)
})
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id == req.params.id)
  if (!user) return res.status(404).json({ error: 'Not found' })
  res.json(user)
})
router.put('/:id', (req, res) => {
  const idx = users.findIndex(u => u.id == req.params.id)
  if (idx === -1) return res.status(404).json({ error: 'Not found' })
  users[idx] = { ...users[idx], ...req.body }
  res.json(users[idx])
})
router.delete('/:id', (req, res) => {
  users = users.filter(u => u.id != req.params.id)
  res.status(204).end()
})

module.exports = router

메인 파일에서 라우터를 연결한다.

const usersRouter = require('./routes/users')
app.use('/users', usersRouter)

미들웨어와 공통 처리

로깅, 오류 처리, 인증 같은 공통 기능을 미들웨어로 관리한다.

로깅 미들웨어

app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`)
  next()
})

에러 핸들러

비동기 오류를 잡아 일관된 응답을 제공한다.

app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).json({ error: 'Internal Server Error' })
})

입력 검증과 보안

사용자 입력 검증은 필수다. 간단한 예로 필수 필드 확인과 타입 검사를 적용한다. 실제 서비스에서는 Joi나 express-validator 사용을 권장한다.

function validateUser(req, res, next) {
  const { name, email } = req.body
  if (!name || !email) return res.status(400).json({ error: 'name, email 필요' })
  next()
}

// router.post('/', validateUser, ...)

보안 측면에서는 CORS 설정, 헤더 보안 강화, HTTPS 적용을 고려한다.

데이터베이스 연결

예제는 메모리 배열을 사용했지만, 실무는 영구 저장소가 필요하다. MongoDB, PostgreSQL 등과 ORM/ODM 사용을 권장한다. 연결은 환경변수로 구성한다.

테스트와 문서화

테스트는 신뢰성을 높인다. Jest나 Mocha로 단위 및 통합 테스트를 작성한다. 또한 OpenAPI(Swagger)로 문서화하면 소비자에게 유용하다.

배포와 운영

배포 환경에서는 프로세스 매니저(pm2), 컨테이너(Docker), 클라우드 서비스(AWS, GCP, Azure)를 고려한다. 로깅과 모니터링 도구를 함께 도입하면 문제 파악이 쉬워진다.

실무적 권장 사항

  • 라우터는 리소스별로 분리한다.
  • 미들웨어는 목적별로 계층화한다.
  • 환경 변수로 민감 정보를 관리한다.
  • 에러 응답 형식은 일관되게 정의한다.
  • API 버전 관리(/v1)를 도입한다.

마무리

이 문서는 Express로 RESTful API를 구현하는 핵심 흐름을 담았다. 초반에는 단순한 구조로 시작해, 요구사항에 맞춰 계층화와 도구를 도입하는 방식이 현실적이다. 작은 API부터 차근히 확장해 가면 운영과 유지보수가 수월해진다.

Express REST API 만들기 Express API 튜토리얼 Node.js RESTful API 구현 Express Node.js REST API CRUD API API 설계