소프트웨어 디자인, 설계

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'))
  • 특징
  1. HTTP 표준을 사용하여 간결하고 직관적
  2. 상태를 저장하지 않는(stateless) 방식으로 확장성 높음
  3. 캐싱 가능하여 성능 향상
  • 장점

  • 간단한 구조로 개발 및 유지보수가 용이

  • 클라이언트와 서버의 독립성 보장

  • 다양한 플랫폼과 호환 가능

  • 단점

  1. Over-fetching (필요 이상의 데이터 조회)
  2. Under-fetching (필요한 데이터를 여러 번 요청해야 함)
  3. 요청이 많아질수록 성능 저하 가능
  • 주의해야 할 사항

  • 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}`))
  • 특징
  1. 클라이언트가 원하는 데이터만 요청 가능
  2. REST보다 유연한 데이터 조회 제공
  3. 단일 엔드포인트(/graphql) 사용
  • 장점

  • Over-fetching & Under-fetching 문제 해결

  • API 변경 시에도 클라이언트가 유연하게 대응 가능

  • 강력한 타입 시스템 제공

  • 단점

  1. 학습 곡선이 높음
  2. 캐싱이 어려움
  3. 서버 부하 증가 가능성
  • 주의해야 할 사항

  • 너무 많은 요청을 하면 서버 성능 저하 가능

  • 캐싱 전략을 명확히 해야 성능 문제 해결 가능

  • 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 네이밍 규칙
  1. 리소스 중심의 네이밍 (예: /users, /products)
  2. 동사 대신 HTTP 메서드 사용 (GET /orders 대신 GET /orders/{id})
  3. 일관성 유지 (소문자 사용, 복수형 리소스)
  4. 버전 관리 고려 (/api/v1/products)
  5. 필터 및 정렬을 위한 쿼리 파라미터 사용 (GET /products?sort=price&limit=10)
  • API 설계 원칙
  1. 일관된 데이터 구조 유지
  2. HTTP 상태 코드 활용3.
  3. 보안 고려 (OAuth, JWT, HTTPS)
  4. 버전 관리 (v1, v2 엔드포인트)
  5. 성능 최적화 (캐싱, 압축 등)

Previous
공통 컴포넌트 설계