소프트웨어 디자인, 설계
API 설계
API 설계는 gRPC, ESB, SOAP, REST, GraphQL, Messaging Queues 등등 많은데요 REST, GraphQL, Messagin Queues 기준으로 기술하겠습니다.
1. REST API
- 정의
REST(Representational State Transfer)는 웹에서 클라이언트와 서버 간의 통신을 설계하는 아키텍처 스타일입니다. HTTP 프로토콜을 기반으로 리소스를 URI로 식별하고, 표준 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 상태를 관리합니다.
많이 사용되는 서비스
웹 애플리케이션 (ex: 블로그, 전자상거래)
모바일 백엔드 API (ex: Android/iOS 앱)
마이크로서비스 아키텍처
예제 (Node.js + Express)
const express = require('express')
const app = express()
app.use(express.json())
let products = [
{ id: 1, name: 'Laptop', price: 1000 },
{ id: 2, name: 'Phone', price: 500 },
]
// GET: 모든 제품 조회
app.get('/products', (req, res) => {
res.json(products)
})
// POST: 새 제품 추가
app.post('/products', (req, res) => {
const newProduct = { id: products.length + 1, ...req.body }
products.push(newProduct)
res.status(201).json(newProduct)
})
// DELETE: 제품 삭제
app.delete('/products/:id', (req, res) => {
products = products.filter((p) => p.id !== parseInt(req.params.id))
res.status(204).send()
})
app.listen(3000, () => console.log('Server running on port 3000'))
- 특징
- HTTP 표준을 사용하여 간결하고 직관적
- 상태를 저장하지 않는(stateless) 방식으로 확장성 높음
- 캐싱 가능하여 성능 향상
장점
간단한 구조로 개발 및 유지보수가 용이
클라이언트와 서버의 독립성 보장
다양한 플랫폼과 호환 가능
단점
- Over-fetching (필요 이상의 데이터 조회)
- Under-fetching (필요한 데이터를 여러 번 요청해야 함)
- 요청이 많아질수록 성능 저하 가능
주의해야 할 사항
RESTful하게 리소스를 URI로 표현해야 함
HTTP 상태 코드(200, 201, 400, 404, 500 등)를 적절히 사용해야 함
보안 고려 (OAuth, JWT 등 활용)
2. GraphQL
- 정의
GraphQL은 클라이언트가 필요한 데이터만 요청하고 받을 수 있도록 하는 API 쿼리 언어입니다. Over-fetching과 Under-fetching 문제를 해결하며, REST보다 유연한 데이터 조회를 제공합니다.
많이 사용되는 서비스
페이스북 (GraphQL을 개발한 기업)
GitHub API
Shopify, Twitter API
예제 (Node.js + Apollo Server)
const { ApolloServer, gql } = require('apollo-server')
const typeDefs = gql`
type Product {
id: ID!
name: String!
price: Float!
}
type Query {
products: [Product]
}
`
const resolvers = {
Query: {
products: () => [
{ id: 1, name: 'Laptop', price: 1000 },
{ id: 2, name: 'Phone', price: 500 },
],
},
}
const server = new ApolloServer({ typeDefs, resolvers })
server.listen().then(({ url }) => console.log(`Server ready at ${url}`))
- 특징
- 클라이언트가 원하는 데이터만 요청 가능
- REST보다 유연한 데이터 조회 제공
- 단일 엔드포인트(
/graphql
) 사용
장점
Over-fetching & Under-fetching 문제 해결
API 변경 시에도 클라이언트가 유연하게 대응 가능
강력한 타입 시스템 제공
단점
- 학습 곡선이 높음
- 캐싱이 어려움
- 서버 부하 증가 가능성
주의해야 할 사항
너무 많은 요청을 하면 서버 성능 저하 가능
캐싱 전략을 명확히 해야 성능 문제 해결 가능
GraphQL 스키마를 적절히 설계해야 함
3. Messaging Queues
- 정의
메시지 큐(Message Queue)는 비동기 데이터 처리를 위한 메시지 기반의 통신 방식입니다. 주로 RabbitMQ, Apache Kafka 등을 사용하며, 대용량 트래픽을 처리할 때 효과적입니다.
많이 사용되는 서비스
주문 처리 시스템 (e-commerce)
금융 거래 시스템
실시간 알림 서비스
예제 (Node.js + RabbitMQ)
const amqp = require('amqplib')
async function sendMessage() {
const connection = await amqp.connect('amqp://localhost')
const channel = await connection.createChannel()
const queue = 'orderQueue'
const message = 'New Order Received'
await channel.assertQueue(queue, { durable: false })
channel.sendToQueue(queue, Buffer.from(message))
console.log(`Sent: ${message}`)
setTimeout(() => connection.close(), 500)
}
sendMessage()
- API 네이밍 규칙
- 리소스 중심의 네이밍 (예:
/users
,/products
) - 동사 대신 HTTP 메서드 사용 (
GET /orders
대신GET /orders/{id}
) - 일관성 유지 (소문자 사용, 복수형 리소스)
- 버전 관리 고려 (
/api/v1/products
) - 필터 및 정렬을 위한 쿼리 파라미터 사용 (
GET /products?sort=price&limit=10
)
- API 설계 원칙
- 일관된 데이터 구조 유지
- HTTP 상태 코드 활용3.
- 보안 고려 (OAuth, JWT, HTTPS)
- 버전 관리 (v1, v2 엔드포인트)
- 성능 최적화 (캐싱, 압축 등)