REST API
REST(Representational State Transfer)는 웹에서 데이터를 전송하는 방식을 정의하는 아키텍처 스타일입니다.
REST API는 HTTP 프로토콜을 기반으로 클라이언트와 서버 간의 통신을 수행하며, 리소스를 중심으로 설계됩니다.
REST의 원칙
(1) 클라이언트-서버 구조 (Client-Server Architecture)
- 클라이언트와 서버는 서로 독립적으로 동작하며, 클라이언트는 요청을 보내고 서버는 응답을 반환합니다.
(2) 무상태성 (Stateless)
- 서버는 클라이언트의 상태를 저장하지 않으며, 각 요청은 독립적으로 처리됩니다.
(3) 캐시 가능 (Cacheable)
- 응답 데이터는 캐시될 수 있으며, 이를 통해 성능을 최적화할 수 있습니다.
(4) 계층화된 시스템 (Layered System)
- 여러 계층을 둬서 보안, 로드 밸런싱 등의 기능을 추가할 수 있습니다.
(5) 인터페이스 일관성 (Uniform Interface)
- RESTful API는 일관된 인터페이스를 유지하며, HTTP 메서드와 URI 설계를 표준화합니다.
REST API의 구성 요소
(1) 리소스(Resource)
- REST에서는 데이터를 "리소스"로 취급하며, 각 리소스는 고유한 URI(Uniform Resource Identifier)를 가집니다.
- 예: https://api.example.com/users/1
(2) HTTP 메서드
메서드설명
| GET | 리소스를 조회합니다. |
| POST | 새로운 리소스를 생성합니다. |
| PUT | 기존 리소스를 수정합니다. |
| DELETE | 리소스를 삭제합니다. |
(3) HTTP 상태 코드
REST API에서는 응답 결과를 HTTP 상태 코드로 나타냅니다.
| 상태 코드 | 의미 |
| 200 OK | 요청 성공 |
| 201 Created | 리소스 생성 성공 |
| 400 Bad Request | 잘못된 요청 |
| 401 Unauthorized | 인증 필요 |
| 404 Not Found | 리소스 없음 |
| 500 Internal Server Error | 서버 오류 |
명확한 리소스 URI 설계
- GET /users (모든 사용자 조회)
- GET /users/1 (특정 사용자 조회)
- POST /users (새로운 사용자 추가)
- PUT /users/1 (특정 사용자 정보 업데이트)
- DELETE /users/1 (특정 사용자 삭제)
쿼리 파라미터 활용
- GET /users?role=admin (관리자 역할을 가진 사용자 조회)
요청 및 응답 형식
- JSON 형식을 기본으로 사용 (Content-Type: application/json)
REST API 예제 (Node.js + Express + TypeScript)
(1) 프로젝트 설정
mkdir rest-api-example && cd rest-api-example
npm init -y
npm install express cors body-parser typescript ts-node @types/node @types/express
(2) server.ts 파일 작성
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
app.use(express.json());
let users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
// GET: 모든 사용자 조회
app.get('/users', (req: Request, res: Response) => {
res.json(users);
});
// GET: 특정 사용자 조회
app.get('/users/:id', (req: Request, res: Response) => {
const user = users.find(u => u.id === Number(req.params.id));
if (user) {
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});
// POST: 새로운 사용자 추가
app.post('/users', (req: Request, res: Response) => {
const newUser = { id: users.length + 1, name: req.body.name };
users.push(newUser);
res.status(201).json(newUser);
});
// PUT: 사용자 정보 업데이트
app.put('/users/:id', (req: Request, res: Response) => {
const user = users.find(u => u.id === Number(req.params.id));
if (user) {
user.name = req.body.name;
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});
// DELETE: 사용자 삭제
app.delete('/users/:id', (req: Request, res: Response) => {
users = users.filter(u => u.id !== Number(req.params.id));
res.status(204).send();
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
(3) 서버 실행
npx ts-node server.ts
React에서 REST API 호출하기
useEffect를 활용한 데이터 가져오기
import React, { useEffect, useState } from 'react';
const UserList = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('http://localhost:3000/users')
.then(response => response.json())
.then(data => setUsers(data))
.catch(error => console.error('Error fetching users:', error));
}, []);
return (
<div>
<h2>User List</h2>
<ul>
{users.map((user: { id: number; name: string }) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
};
export default UserList;
React에서 데이터 추가하기
const addUser = async (name: string) => {
await fetch('http://localhost:3000/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name })
});
};
const updateUser = async (id: number, name: string) => {
await fetch(`http://localhost:3000/users/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name })
});
};
const deleteUser = async (id: number) => {
await fetch(`http://localhost:3000/users/${id}`, {
method: 'DELETE'
});
};
REST API의 장점과 단점
장점
- HTTP 기반으로 간단하고 널리 사용됨
- 캐싱을 활용하여 성능 최적화 가능
- URI를 통해 직관적인 리소스 설계 가능
단점
- Over-fetching(불필요한 데이터 조회) 및 Under-fetching(필요한 데이터 부족) 문제 발생 가능
- API 버전 관리가 필요할 수 있음
- 클라이언트가 여러 API 호출을 해야 할 수도 있음
'개발 공부' 카테고리의 다른 글
| 정규화(Normalization) (0) | 2025.04.27 |
|---|---|
| 웹소켓(WebSocket) (1) | 2025.04.04 |
| Zod 검증 (0) | 2025.03.12 |
| Request Waterfall 방식과 Parallel 방식 (0) | 2025.02.22 |
| Tailwind CSS vs. 다른 프레임워크 (0) | 2025.02.12 |