💡 Key Takeaways
- Resource Naming and URI Design: The Foundation That Everyone Gets Wrong
- HTTP Methods and Status Codes: Speaking the Language Correctly
- Request and Response Design: The Devil in the Details
- Error Handling: When Things Go Wrong (And They Will)
3년 전, 저는 한 스타트업이 사용자 10,000명을 넘지 못하는 API 때문에 230만 달러의 자금을 소진하는 것을 보았습니다. 문제는 그들의 인프라나 데이터베이스 설계가 아니라, 바로 그들의 REST API 아키텍처였습니다. 저는 지난 14년 동안 부실 스타트업에서 포천 500대 기업까지 다양한 회사의 API를 구축하고 유지해온 경험이 있는 사람으로, 이러한 패턴이 제가 세는 것보다 더 많이 반복되는 것을 보았습니다. 저는 주요 핀테크 회사의 수석 API 아키텍트인 Marcus Chen이며, 현재 월 470억 건 이상의 요청을 처리하는 REST API를 설계해 왔습니다. 오늘은 그 스타트업을 구했을 법한 실용적인 체크리스트를 공유하려고 합니다 - 그리고 아마도 여러분의 스타트업도 살릴 수 있을 것입니다.
💡 핵심 요점
- 리소스 이름 지정 및 URI 설계: 모두가 잘못 알고 있는 기초
- HTTP 메소드 및 상태 코드: 올바른 언어로 소통하기
- 요청 및 응답 설계: 세부 사항의 악마
- 오류 처리: 일이 잘못될 때 (그리고 그러할 것이다)
API 개발의 환경은 제가 이 분야에 발을 들인 이후로 극적으로 바뀌었습니다. 2011년에는 API가 JSON을 반환하고 기본 CRUD 작업을 처리할 수 있다면, 이미 앞서나간 것이었습니다. 2026년에는 기준이 기하급수적으로 높아졌습니다. 여러분의 API는 안전하고, 성능이 뛰어나며, 가시성이 있어야 하고, 개발자 친화적이어야 합니다 - 동시에 5년 전에는 존재하지 않았던 엣지 케이스를 처리하면서요. 이는 블로그 게시글 몇 개를 읽은 사람의 이론적인 조언이 아닙니다. 이는 새벽 3시에 실제 운영 중인 사고를 디버깅하고, 하루에 수천 달러의 클라우드 요금을 초래했던 엔드포인트를 최적화하고, 실제 세상에서 작동하는 API 설계 원칙에 대해 수십 명의 엔지니어를 교육한 사람의 전투 검증된 지혜입니다.
리소스 이름 지정 및 URI 설계: 모두가 잘못 알고 있는 기초
기본적인 것처럼 보이지만 경험이 많은 개발자들을 쉽게 넘어뜨리는 것부터 시작하겠습니다: 리소스 이름 지정. 지난 분기, 저는 우리 조직의 서로 다른 23개 팀의 API를 검토했습니다. 그 중 19개 팀은 API 사용 및 유지 보수를 더 어렵게 만든 일관되지 않은 이름 지정 규약을 가지고 있었습니다. 이것은 단지 미적에 관한 것이 아닙니다 - 잘못된 이름 지정은 개발자 경험에 직접적인 영향을 미치며, 이는 느린 통합 시간 및 더 많은 지원 티켓으로 이어집니다.
기본 원칙은 이렇습니다: URI는 리소스를 나타내야 하고, 행동을 나타내서는 안 됩니다. 동사가 아닌 명사를 사용하세요. 저는 이 실수를 끊임없이 봅니다: /getUser 또는 /createOrder와 같은 엔드포인트. 이는 REST를 가장한 RPC 스타일의 엔드포인트입니다. 올바른 접근 방식은 행동을 나타내기 위해 HTTP 메소드를 사용하는 것입니다: GET /users/123 또는 POST /orders. 이 점은 사소하게 보일 수 있지만, 매우 중요합니다. 제가 결제 처리 API를 이 패턴에 맞춰 일관되게 리팩토링 했을 때, 새로운 파트너와의 통합 시간이 평균 8.3일에서 4.1일로 줄어들었습니다.
컬렉션에는 항상 복수형 명사를 사용하세요. 저는 문법적으로 어색하든 상관하지 않겠습니다 - 일관성이 문법을 초월합니다. 여러분의 엔드포인트는 /users여야 하고, /user가 되어서는 안 됩니다. 단수형과 복수형을 혼합하면 개발자가 임의의 결정을 외워야 합니다. 저는 팀들이 엔드포인트가 단수형이어야 하는지 복수형이어야 하는지 회의에서 몇 시간씩 논의하는 것을 보았습니다. 여러분의 머리를 아프게 하지 마세요: 컬렉션에는 항상 복수형을 사용하세요.
계층적 관계는 URI 구조에 반영되어야 하지만, 세 수준 이상으로 깊이 들어가서는 안 됩니다. 예를 들어, /users/123/orders/456/items/789는 다루기 힘들어지고 있습니다. 그 지점에서는 아이템을 필터링할 수 있는 최상위 리소스로 만드는 것을 고려하세요: /items?orderId=456. 저는 다섯 수준 깊은 중첩으로 전자 상거래 API를 구축했을 때 이 교훈을 힘들게 배웠습니다. 그 코드는 유지보수가 불가능해졌고, 우리는 두 달을 리팩토링하는 데 보냈습니다.
URI에서는 밑줄 대신 하이픈을 사용하세요. 이는 가독성을 향상시키는 사소한 세부 사항입니다: /order-items는 /order_items보다 읽기 쉽습니다. 더 중요한 것은, 일부 시스템은 밑줄을 다르게 처리하고, 하이픈은 보편적으로 안전합니다. 모든 것을 소문자로 유지하세요. URI에서 혼합 대문자는 문제를 일으키는 초대입니다, 왜냐하면 일부 시스템은 대소문자를 구별하지만 다른 시스템은 그렇지 않기 때문입니다.
API 버전 관리를 첫날부터 시작하세요. 이 점은 분명히 강조하고 싶습니다. /v1/users 또는 /v2/orders와 같은 URI 버전 관리를 사용하세요. 저는 헤더 기반 버전 관리, 쿼리 매개변수 버전 관리 및 콘텐츠 협상을 시도해 보았습니다. URI 버전 관리는 가장 간단하고 가장 적은 머리 아픔을 유발합니다. 우리가 버전 없이 API를 출시했을 때, 우리는 6개월 이내에 벽에 부딪혔습니다. 깨지는 변경 사항은 기존 통합에 혼란을 주지 않고 배포하는 것이 불가능해졌습니다.
HTTP 메소드 및 상태 코드: 올바른 언어로 소통하기
리소스 이름 지정이 기초라면, HTTP 메소드 및 상태 코드는 REST API의 문법입니다. 이를 올바르게 사용하는 것은 선택 사항이 아닙니다 - 이는 API 소비자에게 의도와 결과를 전달하는 방법입니다. 저는 개발자들이 HTTP 메소드를 사양이 아닌 제안으로 취급하는 수백 개의 API를 검토해왔습니다. 이는 혼란을 일으키고, 캐싱을 깨트리며, 여러분의 API를 예측할 수 없게 만듭니다.
"여러분의 API 리소스 이름 지정은 단순히 미적 에 대한 것이 아닙니다 - 이는 개발자들이 며칠 안에 통합하는 것과 몇 주가 걸리는 것의 차이며, 이는 여러분의 수익에 직접적인 영향을 미칩니다."
GET 요청은 안전하고 항등적이어야 합니다. 안전하다는 것은 서버 상태를 변경하지 않는다는 의미입니다. 항등적이라는 것은 여러 번 호출해도 동일한 결과를 생성한다는 의미입니다. 저는 GET 요청이 데이터베이스 레코드를 생성하는 API를 인수인계 받은 적이 있습니다. 이것이 초래한 혼란은 엄청났습니다 - 브라우저 프리패칭 및 링크 크롤러가 수천 개의 허위 레코드를 생성했습니다. 우리는 이 엉망진창을 정리하고 설계를 수정하는 데 3주가 걸렸습니다.
POST는 리소스를 생성하는 데 사용됩니다. /orders로 POST할 때, 여러분은 새 주문을 생성하는 것입니다. 응답은 새 리소스를 가리키는 Location 헤더와 함께 201 Created를 반환해야 합니다: Location: /orders/789. 생성된 리소스를 응답 본문에 포함하세요. 이렇게 하면 클라이언트가 추가 GET 요청을 하지 않아도 됩니다. 우리 주문 처리 시스템에서는 이 간단한 최적화가 API 호출을 31% 줄였고, 인지된 성능을 상당히 개선했습니다.
PUT은 전체 업데이트에 사용되며 항등적이어야 합니다. /users/123에 동일한 데이터를 10번 PUT하면 결과는 한 번 수행한 것과 동일해야 합니다. PATCH는 부분 업데이트에 사용합니다. 클라이언트가 변경된 필드만 전송할 경우 PATCH를 사용하세요. 이는 페이로드 크기를 줄이고 업데이트를 더 효율적으로 만듭니다. 우리의 사용자 프로파일 API에서는 프로파일 업데이트에 대해 PUT에서 PATCH로 전환하여 평균 페이로드 크기를 4.2KB에서 0.8KB로 줄였습니다.
DELETE는 성공적인 삭제에 대해 204 No Content를 반환해야 합니다. 일부 개발자는 확인 메시지와 함께 200 OK를 반환하지만, 204가 더 의미상 올바릅니다 - 리소스가 사라졌기 때문에 반환할 내용이 없습니다. DELETE도 항등적으로 만드세요. 이미 삭제된 리소스를 삭제하면 204를 반환해야 하며, 404는 반환해서는 안 됩니다. 이는 분산 시스템의 경합 조건을 방지합니다.
상태 코드는 여러분이 생각하는 것보다 더 중요합니다. 성공적인 GET, PUT 및 PATCH 요청에 대해서는 200 OK를 사용하세요. 성공적인 POST 요청에 대해서는 201 Created를 사용하세요. 성공적인 DELETE 요청에 대해서는 204 No Content를 사용하세요.