브라우저에서만 동작하던 JavaScript를 서버에서도 실행할 수 있게 해주는 것이 Node.js입니다. Google V8 엔진 위에서 동작하며, 빠른 I/O와 이벤트 기반 아키텍처로 API 서버, 실시간 서비스에 적합합니다.

Node.js 기본 — HTTP 서버

// server.js
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ message: '안녕하세요!' }));
});

server.listen(3000, () => {
  console.log('서버 실행 중: http://localhost:3000');
});

파일 시스템 다루기

const fs = require('fs/promises');
const path = require('path');

async function readConfig() {
  const filePath = path.join(__dirname, 'config.json');
  const content = await fs.readFile(filePath, 'utf-8');
  return JSON.parse(content);
}

async function writeLog(message) {
  const logPath = path.join(__dirname, 'logs', 'app.log');
  const line = `[${new Date().toISOString()}] ${message}\n`;
  await fs.appendFile(logPath, line);
}

Express로 REST API 만들기

npm init -y
npm install express
// app.js
const express = require('express');
const app = express();

app.use(express.json()); // JSON 요청 파싱

// 인메모리 데이터 (실제로는 DB 사용)
let posts = [
  { id: 1, title: 'Node.js 입문', content: '...' },
  { id: 2, title: 'Express 가이드', content: '...' },
];

// GET — 목록 조회
app.get('/api/posts', (req, res) => {
  res.json(posts);
});

// GET — 단건 조회
app.get('/api/posts/:id', (req, res) => {
  const post = posts.find(p => p.id === Number(req.params.id));
  if (!post) return res.status(404).json({ error: '없는 글입니다' });
  res.json(post);
});

// POST — 생성
app.post('/api/posts', (req, res) => {
  const { title, content } = req.body;
  if (!title) return res.status(400).json({ error: '제목은 필수입니다' });

  const newPost = { id: Date.now(), title, content };
  posts.push(newPost);
  res.status(201).json(newPost);
});

// PUT — 수정
app.put('/api/posts/:id', (req, res) => {
  const idx = posts.findIndex(p => p.id === Number(req.params.id));
  if (idx === -1) return res.status(404).json({ error: '없는 글입니다' });

  posts[idx] = { ...posts[idx], ...req.body };
  res.json(posts[idx]);
});

// DELETE — 삭제
app.delete('/api/posts/:id', (req, res) => {
  posts = posts.filter(p => p.id !== Number(req.params.id));
  res.status(204).send();
});

app.listen(3000, () => console.log('🚀 서버 시작: http://localhost:3000'));

미들웨어 패턴

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

// 인증 미들웨어
function requireAuth(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: '로그인이 필요합니다' });
  // 토큰 검증 로직...
  next();
}

// 특정 라우트에만 적용
app.delete('/api/posts/:id', requireAuth, (req, res) => {
  // 인증된 사용자만 삭제 가능
});

환경 변수 관리

npm install dotenv
// .env 파일
PORT=3000
DB_URL=mongodb://localhost:27017/mydb
JWT_SECRET=my-super-secret-key

// app.js
require('dotenv').config();
const PORT = process.env.PORT || 3000;
app.listen(PORT);
핵심 정리
Node.js는 JavaScript를 서버에서 실행합니다. Express로 빠르게 REST API를 구성하고, 미들웨어 패턴으로 인증·로깅·에러 처리를 분리하세요. 실제 서비스라면 데이터베이스(MongoDB, PostgreSQL)와 연동해 데이터를 영속적으로 저장해야 합니다.