프로그래밍/NODEJS 강좌 BY GEMINI

RESTful API 설계 및 구현 🏗️

lazy_web_devloper 2025. 7. 2. 10:10
728x90
반응형

RESTful API 설계 및 구현 🏗️

최근의 웹 서비스는 프론트엔드(React, Vue, Angular 같은 웹 앱)와 백엔드(서버)가 분리된 구조를 가집니다. 또한, 모바일 앱(iOS, Android)도 동일한 백엔드 서버를 사용하는 경우가 많습니다. 이런 환경에서는 서버가 HTML 페이지를 보내주는 대신, 모든 클라이언트가 공통적으로 사용할 수 있는 데이터를 표준화된 방식으로 제공해야 합니다.

이때 사용되는 가장 보편적인 아키텍처 스타일이 바로 REST (Representational State Transfer) 이며, REST 원칙을 따르는 API를 RESTful API라고 부릅니다.

Java 개발자를 위한 비유

Express로 RESTful API를 만드는 것은 Spring Boot에서 @RestController 어노테이션을 사용하여 REST 컨트롤러를 만드는 것과 정확히 같은 목적을 가집니다. Express의 라우팅 메소드들은 Spring의 @GetMapping, @PostMapping 등과 직접적으로 매칭되며, 데이터 처리 방식도 매우 유사합니다.


1. REST의 핵심 원칙

RESTful API는 다음 원칙을 중심으로 설계됩니다.

  • 자원 (Resource): API가 다루는 모든 것을 자원으로 봅니다. (예: 사용자, 게시글, 상품).
  • URI (Uniform Resource Identifier): 각 자원은 고유한 URI(URL 경로)를 통해 식별됩니다. URI는 명사를 사용하여 자원을 표현합니다. (예: /users, /posts/123).
  • HTTP 메소드 (Method): 자원에 대한 행위(Create, Read, Update, Delete)는 HTTP 메소드를 통해 표현합니다.
작업 (CRUD) HTTP 메소드 예시 URI 설명
Create POST /users 새로운 사용자를 생성합니다.
Read GET /users 또는 /users/123 사용자 목록 또는 특정 사용자를 조회합니다.
Update PUT / PATCH /users/123 특정 사용자의 정보를 수정합니다.
Delete DELETE /users/123 특정 사용자를 삭제합니다.
Sheets로 내보내기
  • 표현 (Representation): 클라이언트와 서버는 자원의 상태를 특정 형태(Representation)로 주고받습니다. 현재는 대부분 JSON (JavaScript Object Notation) 형식이 사용됩니다.

2. Express로 REST API 구현하기

간단한 사용자(User) 관리 API를 Express로 구현해 보겠습니다. 데이터베이스 연동은 아직 배우지 않았으므로, 메모리 상의 배열을 데이터베이스처럼 사용하겠습니다.

app.js

JavaScript
 
const express = require('express');
const app = express();
const port = 3000;

// JSON 요청 본문을 파싱하기 위한 미들웨어
app.use(express.json());

// 메모리 내 데이터베이스 (배열)
let users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

// --- API 라우트 정의 ---

// 1. 모든 사용자 조회 (Read)
// GET /api/users
app.get('/api/users', (req, res) => {
  res.json(users);
});

// 2. 특정 사용자 조회 (Read)
// GET /api/users/:id
app.get('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  const user = users.find(u => u.id === userId);

  if (user) {
    res.json(user);
  } else {
    // 사용자를 찾지 못한 경우 404 상태 코드와 에러 메시지 반환
    res.status(404).json({ message: 'User not found' });
  }
});

// 3. 새로운 사용자 생성 (Create)
// POST /api/users
app.post('/api/users', (req, res) => {
  const newUser = {
    id: users.length ? Math.max(...users.map(u => u.id)) + 1 : 1,
    name: req.body.name
  };

  if (!newUser.name) {
    return res.status(400).json({ message: 'Name is required' });
  }

  users.push(newUser);
  // 생성 성공 시 201 상태 코드와 생성된 리소스를 반환
  res.status(201).json(newUser);
});

// 4. 사용자 정보 수정 (Update)
// PUT /api/users/:id
app.put('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  const user = users.find(u => u.id === userId);

  if (user) {
    user.name = req.body.name || user.name;
    res.json(user);
  } else {
    res.status(404).json({ message: 'User not found' });
  }
});

// 5. 사용자 삭제 (Delete)
// DELETE /api/users/:id
app.delete('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  const initialLength = users.length;
  users = users.filter(u => u.id !== userId);

  if (users.length < initialLength) {
    // 삭제 성공 시 204 상태 코드는 본문을 보내지 않음을 의미
    res.status(204).send();
  } else {
    res.status(404).json({ message: 'User not found' });
  }
});


app.listen(port, () => {
  console.log(`API server listening at http://localhost:${port}`);
});

API 테스트:

Postman이나 curl 같은 도구를 사용하여 위 API를 테스트할 수 있습니다.

  • GET http://localhost:3000/api/users
  • POST http://localhost:3000/api/users (Body: { "name": "David" })
  • GET http://localhost:3000/api/users/4
  • DELETE http://localhost:3000/api/users/2

이 예제는 Express를 사용하여 어떻게 RESTful API의 기본 구조를 빠르고 간결하게 구현할 수 있는지 보여줍니다. 각 라우트는 명확한 책임을 가지며, HTTP 메소드와 상태 코드를 통해 클라이언트와 명확하게 소통합니다.


이것으로 "5️⃣ Express.js로 강력한 웹 애플리케이션 구축하기 🌐" 챕터를 마무리하겠습니다. Express를 사용하면 전통적인 서버사이드 렌더링 웹사이트부터 현대적인 REST API 서버까지 다양한 형태의 웹 애플리케이션을 손쉽게 만들 수 있습니다.

728x90
반응형