현대 웹 개발에서 RESTful API는 서버와 클라이언트 간의 원활한 데이터 전송 및 상호작용을 위해 필수적인 개념입니다. Express.js는 Node.js 환경에서 RESTful API를 구축하기 위한 간편하고 강력한 프레임워크로 자리잡았습니다. 이번 글에서는 RESTful API의 개념, 설계 원칙, 그리고 Express를 사용한 예제 코드를 통해 이를 이해해 보겠습니다.
1. RESTful API란?
REST(Representational State Transfer)는 웹 아키텍처 스타일 중 하나로, HTTP 프로토콜을 기반으로 합니다. RESTful API는 이러한 REST의 원칙을 준수하여 클라이언트와 서버가 통신하는 방식입니다. RESTful API를 사용하면 다양한 클라이언트가 서버의 자원에 접근하고 상호작용할 수 있으며, 이 자원은 URI(Uniform Resource Identifier)를 통해 식별됩니다.
1.1. REST의 주요 특징
- 무상태성(Stateless): 각 요청은 독립적이며, 서버는 클라이언트의 상태를 저장하지 않습니다.
- 자원 기반(Resource-Based): 자원은 URI로 식별되며, HTTP 메소드를 통해 자원에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행합니다.
- 표현(Representation): 클라이언트와 서버 간의 데이터 교환은 주로 JSON, XML 등의 형식으로 이루어집니다.
- 캐시 가능(Cacheable): 응답은 캐시 가능하므로 클라이언트는 동일한 자원에 대한 후속 요청을 삭제할 수 있습니다.
2. RESTful API의 설계 원칙
RESTful API를 설계할 때 준수해야 할 몇 가지 원칙이 있습니다. 이는 API의 일관성과 사용성을 보장하는 데 도움이 됩니다.
2.1. 자원(URL)의 설계
RESTful API는 자원 중심으로 설계되어야 하며, 각 자원은 고유한 URI로 식별됩니다. URI는 의미론적으로 이해할 수 있어야 하며, 다음과 같은 규칙을 따릅니다:
- 복수형을 사용하여 자원을 표현합니다: 예를 들어, 사용자를 나타내는 자원은
/users
로 표현합니다. - 계층적 구조로 설계합니다: 자원 간의 관계를 고려하여 URI를 설계합니다. 예를 들어, 특정 사용자의 포스트를 나타내는 자원은
/users/:userId/posts
로 표현할 수 있습니다.
2.2. HTTP 메소드의 활용
자원에 대한 작업은 다음의 HTTP 메소드를 사용하여 수행합니다:
- GET: 자원 조회 (ex.
GET /users
) - POST: 자원 생성 (ex.
POST /users
) - PUT: 자원 전체 업데이트 (ex.
PUT /users/:userId
) - PATCH: 자원 부분 업데이트 (ex.
PATCH /users/:userId
) - DELETE: 자원 삭제 (ex.
DELETE /users/:userId
)
2.3. 상태 코드의 활용
HTTP 상태 코드는 클라이언트에게 요청 처리 결과를 전달하는 데 필요합니다. 다음은 자주 사용되는 상태 코드입니다:
200 OK
: 성공적인 요청201 Created
: 자원 생성 성공204 No Content
: 요청 성공, 반환할 데이터 없음400 Bad Request
: 잘못된 요청404 Not Found
: 자원 없음500 Internal Server Error
: 서버 에러
2.4. 버전 관리
API가 진화함에 따라 기존의 API와 호환되지 않는 변경이 있을 수 있습니다. 따라서 API 버전을 명시하여 클라이언트가 특정 버전을 사용하도록 합니다. 일반적으로 URL에 버전 번호를 포함시킵니다:
/v1/users
3. Express.js를 이용한 RESTful API 구축
이제 Express.js를 사용하여 간단한 RESTful API를 구축해 보겠습니다. 이 예제에서는 사용자 정보를 관리하는 API를 구현합니다.
3.1. Express 프로젝트 설정
먼저, Express 프로젝트를 생성합니다. Node.js가 설치되어 있어야 하며, 새로운 프로젝트를 만들고 필요한 패키지를 설치합니다:
mkdir express-api-example
cd express-api-example
npm init -y
npm install express body-parser
3.2. 기본 서버 설정
아래의 코드로 server.js
파일을 생성하고 기본 Express 서버를 설정합니다:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const PORT = 3000;
// Middleware
app.use(bodyParser.json());
// 기본 라우터
app.get('/', (req, res) => {
res.send('Welcome to the Express RESTful API!');
});
// 서버 실행
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
3.3. RESTful API 엔드포인트 생성
이제 사용자 정보를 관리하기 위한 CRUD 엔드포인트를 추가해 보겠습니다.
// 가상의 사용자 데이터를 저장하기 위한 배열
let users = [];
// GET: 사용자 목록 조회
app.get('/users', (req, res) => {
res.json(users);
});
// GET: 특정 사용자 조회
app.get('/users/:userId', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.userId));
if (!user) return res.status(404).send('User not found');
res.json(user);
});
// POST: 사용자 추가
app.post('/users', (req, res) => {
const user = {
id: users.length + 1,
name: req.body.name,
email: req.body.email
};
users.push(user);
res.status(201).json(user);
});
// PUT: 사용자 정보 수정
app.put('/users/:userId', (req, res) => {
let user = users.find(u => u.id === parseInt(req.params.userId));
if (!user) return res.status(404).send('User not found');
user.name = req.body.name;
user.email = req.body.email;
res.json(user);
});
// DELETE: 사용자 삭제
app.delete('/users/:userId', (req, res) => {
users = users.filter(u => u.id !== parseInt(req.params.userId));
res.status(204).send();
});
3.4. 서버 실행 및 테스트
서버를 실행합니다:
node server.js
브라우저나 Postman과 같은 API 클라이언트를 사용하여 엔드포인트를 테스트할 수 있습니다.
4. API 문서화
RESTful API를 개발한 후에는 문서화가 필요합니다. 문서화는 API 사용자가 API를 쉽게 이해하고 사용할 수 있도록 도와줍니다. Swagger, Postman과 같은 도구를 사용하여 쉽게 문서화할 수 있습니다. Swagger UI를 사용하면 API 문서를 시각적으로 작성할 수 있습니다.
5. 결론
이번 글에서는 Express.js를 사용한 RESTful API의 개념과 설계 원칙을 살펴보았습니다. RESTful API는 웹 애플리케이션의 필수적인 부분이며, Express.js를 사용하여 간단하고 효율적으로 구축할 수 있습니다. 설계 원칙을 지킴으로써 사용자는 API를 더욱 쉽게 활용할 수 있습니다. 이러한 원칙을 바탕으로 여러분의 프로젝트에 적합한 RESTful API를 구축해 보시기 바랍니다.