💡 오늘 학습 키워드
- 좋은 API란 무엇인가?
- API 설계가 중요한 이유
- Kafka/RabbitMQ 적용
🎯 학습 내용 정리
Spring Boot 프로젝트를 진행하다 보면 가장 많이 작성하는 기능 중 하나가 API이다. 회원가입 API, 주문 생성 API, 상품 조회 API처럼 대부분의 기능은 API를 중심으로 구현된다. 처음에는 단순히 Controller를 만들고 Service를 호출한 뒤 데이터를 반환하면 된다고 생각하기 쉽다.
하지만 프로젝트 규모가 커질수록 API는 단순히 데이터를 주고받는 통신 수단이 아니라 시스템 전체의 인터페이스 역할을 수행하게 된다. 한 번 공개된 API는 프론트엔드, 모바일 애플리케이션, 다른 백엔드 서비스 등 다양한 클라이언트가 의존하게 되므로 이후 구조를 변경하기도 쉽지 않다.
실제로 실무에서는 비즈니스 로직보다 API 설계에 더 많은 시간을 투자하는 경우도 적지 않다. API 구조가 잘못 설계되면 같은 기능을 구현하더라도 중복 API가 계속 생기고, URI 규칙이 일관되지 않으며, 요청과 응답 형식도 제각각이 된다. 결국 기능은 동작하지만 개발 속도는 점점 느려지고 유지보수 비용은 계속 증가한다.
반대로 처음부터 일정한 원칙을 가지고 API를 설계하면 새로운 기능을 추가하더라도 기존 구조를 그대로 활용할 수 있으며, 다른 개발자도 API의 형태를 쉽게 예측할 수 있다. 이러한 이유로 좋은 API를 만드는 것은 단순한 코딩 기술이 아니라 프로젝트 전체의 생산성과 유지보수성을 결정하는 중요한 설계 과정이라고 볼 수 있다.
이번 글에서는 REST API 문법을 설명하기보다 '좋은 API란 무엇인지', 그리고 왜 설계가 중요한지를 중심으로 정리해보려고 한다.
1. 좋은 API란 무엇인가?
API(Application Programming Interface)는 서로 다른 애플리케이션이 데이터를 주고받기 위한 인터페이스이다. Spring Boot에서는 대부분 HTTP 기반의 REST API 형태로 제공하며, 클라이언트는 HTTP 요청을 보내고 서버는 그에 대한 응답을 반환한다.
간단한 구조는 다음과 같다.
Client
│
HTTP Request
│
Controller
│
Service
│
Repository
│
Database
│
HTTP Response
│
Client
겉으로 보기에는 단순한 요청과 응답처럼 보이지만, 실제로는 API 하나가 여러 시스템을 연결하는 약속(Contract)의 역할을 수행한다.
예를 들어 회원 정보를 조회하는 API가 있다고 가정해 보자.
GET /users/1
클라이언트는 이 API를 호출하면 회원 정보를 받을 것이라고 기대한다.
{
"id": 1,
"name": "Kim",
"email": "kim@example.com"
}
만약 서버 개발자가 어느 날 갑자기 응답 구조를 다음과 같이 변경한다면 어떨까?
{
"userId": 1,
"userName": "Kim",
"mail": "kim@example.com"
}
서버는 정상적으로 동작하지만 기존 클라이언트는 모두 오류가 발생한다.
즉, API는 단순한 함수 호출이 아니라 여러 시스템이 함께 사용하는 계약이라고 이해해야 한다.
좋은 API는 이러한 계약을 안정적으로 유지하면서도 개발자가 쉽게 이해하고 사용할 수 있도록 설계된 API를 의미한다.
1) 단순히 동작하는 API와 좋은 API는 다르다.
프로젝트를 처음 진행할 때는 "기능만 동작하면 되는 것 아닌가?"라는 생각을 하기 쉽다.
예를 들어 아래와 같은 API도 기능은 정상적으로 수행할 수 있다.
GET /getUser
POST /userDelete
POST /userUpdate
GET /userList
요청도 되고 응답도 잘 온다.
그렇다면 이것도 좋은 API일까?
처음에는 문제가 없어 보이지만 프로젝트 규모가 커질수록 여러 문제가 발생한다.
예를 들어 사용자 API를 담당하는 개발자는 /userList를 사용하고, 주문 API를 담당하는 개발자는 /orders/getOrders를 사용하며, 상품 API는 /product/all이라는 URI를 사용한다면 프로젝트 전체에 규칙이 존재하지 않게 된다.
새로운 개발자가 프로젝트에 합류했을 때도 API 이름을 예측하기 어렵다.
반대로 다음과 같이 일정한 규칙을 적용한다면 어떨까?
GET /users
GET /users/{id}
POST /users
PATCH /users/{id}
DELETE /users/{id}
URI만 보더라도 어떤 동작을 수행하는 API인지 쉽게 예측할 수 있다.
좋은 API는 새로운 문서를 보지 않아도 어느 정도 동작을 예상할 수 있어야 한다.
즉, 예측 가능성(Predictability) 역시 좋은 API의 중요한 요소 중 하나이다.
2) 좋은 API는 사람이 읽기 쉬워야 한다.
API는 컴퓨터만 사용하는 것이 아니다.
결국 API를 설계하고 사용하는 것은 개발자이다.
예를 들어 다음 두 URI를 비교해 보자.
GET /api/getUserInfoByUserId
GET /users/{id}
둘 다 같은 기능을 수행하지만 두 번째가 훨씬 직관적이다.
REST에서는 URI를 동사가 아니라 리소스(Resource) 중심으로 표현하는 이유도 여기에 있다.
URI는 "무엇(Resource)"을 표현하고,
HTTP Method는 "무엇을 할 것인가(Action)"를 표현한다.
GET /users/1
라는 URI를 보면
users
라는 리소스를
GET
으로 조회한다는 의미를 쉽게 이해할 수 있다.
API를 읽는 사람은 코드보다 먼저 URI를 보게 된다.
따라서 URI는 최대한 자연스럽고 일관된 형태를 유지하는 것이 좋다.
3) API는 시스템 간의 언어이다.
사람과 사람이 대화할 때도 같은 언어를 사용해야 원활하게 의사소통할 수 있다.
API 역시 마찬가지이다.
프론트엔드와 백엔드, 모바일과 서버, MSA 환경에서는 서비스와 서비스가 API를 통해 통신한다.
Order Service
│
│
Product Service
│
│
User Service
각 서비스가 서로 다른 규칙으로 API를 만든다면 통신은 가능하더라도 협업 비용은 계속 증가한다.
예를 들어 상품 서비스에서는
GET /products
를 사용하지만,
주문 서비스에서는
GET /getOrders
를 사용하고,
사용자 서비스에서는
POST /findUser
를 사용한다면 개발자는 서비스마다 서로 다른 규칙을 외워야 한다.
반대로 모든 서비스가 동일한 규칙을 따른다면 새로운 API를 설계하는 비용도 줄어들고 협업 역시 훨씬 수월해진다.
좋은 API는 기능을 제공하는 것뿐만 아니라 시스템 전체가 동일한 언어를 사용할 수 있도록 만들어 주는 역할도 수행한다.
2. API 설계가 중요한 이유
API는 한 번 구현하고 끝나는 코드가 아니다.
대부분의 프로젝트에서는 새로운 기능이 계속 추가되고 기존 기능도 지속적으로 변경된다. 처음에는 회원 관리 API 몇 개로 시작했던 프로젝트도 시간이 지나면 주문, 결제, 배송, 리뷰, 알림 등 수십 개의 도메인이 추가된다.
이 과정에서 설계 원칙 없이 API를 작성하면 프로젝트는 빠르게 복잡해진다.
예를 들어 회원 조회 API가 처음에는 하나뿐이었다고 가정해 보자.
GET /users/{id}
이후 검색 기능이 추가되면서 다음과 같은 API가 만들어진다.
GET /getUserList
관리자 전용 조회 기능이 필요해지자 또 다른 API가 생긴다.
GET /admin/users
이후 탈퇴 회원 조회 기능이 추가된다.
GET /deletedUserList
기능은 계속 동작하지만 프로젝트 전체를 보면 URI 규칙이 점점 무너진다. 검색 기능은 getUserList, 관리 기능은 admin/users, 삭제된 회원은 deletedUserList처럼 서로 다른 기준으로 설계되어 있기 때문이다.
이러한 문제는 단순히 URI가 보기 좋지 않은 수준에서 끝나지 않는다. API가 늘어날수록 새로운 기능을 추가할 때마다 기존 규칙을 파악하는 시간이 길어지고, 비슷한 기능을 하는 API가 중복 생성되기도 한다. 결국 유지보수 비용은 계속 증가하고, 팀원 간의 협업도 어려워진다.
반대로 초기에 명확한 설계 원칙을 세우면 이후 기능이 늘어나더라도 동일한 패턴을 유지할 수 있다.
예를 들어 회원 목록 조회 API가 이미 존재한다면 검색 기능은 Query Parameter를 활용하여 자연스럽게 확장할 수 있다.
GET /users
GET /users?name=kim
GET /users?role=MASTER
GET /users?status=ACTIVE
URI를 새롭게 만들기보다 기존 리소스를 확장하는 방식이므로 일관성을 유지할 수 있다.
📚 한줄 정리
좋은 API는 단순히 요청과 응답이 가능한 인터페이스가 아니라, 여러 시스템과 개발자가 오랫동안 함께 사용할 수 있도록 일관성과 예측 가능성을 갖춘 계약이다.
'Bootcamp > Fundamentals' 카테고리의 다른 글
| GHCR (0) | 2026.08.17 |
|---|---|
| 좋은 API 설계란? - 2편 (1) | 2026.08.04 |
| Spring AI Fundamentals (0) | 2026.07.31 |
| Webhook을 이용한 Slack 알림 전송과 Kafka/RabbitMQ 적용 (0) | 2026.07.30 |
| DDD Layered Architecture / Hexagonal Architecture (0) | 2026.07.29 |