좋은 API는 가장 좋은 의미에서 지루합니다. 예측 가능한 URL, 솔직한 오류 응답, 작고 안정적인 스키마, 놀라울 일이 없죠. 아래 원칙은 Noxyr Server API의 설계를 이끈 것들로, Stripe, Resend, OpenAI, 그리고 공식 Discord API 뒤에 있는 업계 표준에서 가져왔습니다.
1. 버전이 붙은 URL
모든 엔드포인트는 /api/v1/ 아래에 있습니다. 하위 호환이 깨지는 변경은 /api/v2/에 들어가므로 기존 연동은 계속 동작합니다. Discord도 /api/v10/으로 같은 방식을 씁니다. API에 버전이 없으면 스키마가 바뀔 때마다 고객 지원 문의가 쏟아집니다.
2. 리소스가 먼저, 동작은 그다음
Noxyr 엔드포인트는 server, tickets, activity, invoices, reviews, giveaways처럼 명사로 이름을 붙입니다. 지금은 모두 읽기 전용이라 전부 GET입니다. 쓰기 기능이 추가되면 같은 리소스에 POST/PATCH/DELETE가 붙습니다. 이렇게 하면 REST 관례와 깔끔하게 맞고, 머릿속에 담아야 할 모델도 아주 작아집니다.
3. 베어러 토큰, 비밀 값 하나
인증은 Authorization: Bearer nxr_... 형식입니다. 서명된 요청도, 읽기 전용 서버 데이터를 위한 OAuth 흐름도 없습니다. curl, 브라우저, Postman, 서버리스 엣지 등 어디서나 동작하기 때문에 개발자용 API들이 대부분 이 방식으로 모입니다. Discord도 OAuth로 인증된 사용자에게 베어러 토큰을 씁니다. 이 패턴은 어디에나 통합니다.
4. 해시만 저장
모든 Noxyr 키는 서버에서 SHA-256으로 해시해 저장합니다. 원본 값은 생성할 때 한 번만 보여 주고 다시는 보여 주지 않습니다. 데이터베이스가 유출되더라도 사용할 수 있는 키는 없습니다. Stripe, GitHub, Resend 등 제대로 운영되는 API 업체는 모두 이렇게 하며, 되돌릴 수 있는 키 저장 방식은 위험 신호입니다.
5. 세분화된 범위
키 하나에 독립된 토글 여섯 개가 있습니다. 리뷰는 공개 데이터이고 매출은 비공개입니다. 이를 나누면 리뷰 전용 키만 마케팅 파트너에게 공유하고, 매출 수치는 다른 토글 뒤에 둘 수 있습니다. 범위를 바꾸면 모든 요청에서 즉시 확인되므로, 키를 교체하지 않고도 접근을 취소할 수 있습니다.
6. 솔직한 오류 응답
모든 오류는 변하지 않는 기계용 코드와 사람이 읽을 메시지가 담긴 JSON입니다:
{ "error": "scope_disabled", "message": "The \"tickets\" scope is turned off for this key. Enable it on the dashboard API page." }
기계가 읽을 수 있는 코드 덕분에 재시도와 대시보드 구현이 쉬워지고, 사람이 읽을 메시지 덕분에 디버깅이 빨라집니다. 2026년 7월 "discord increased api errors" 검색이 급상승(Google 트렌드 '브레이크아웃')한 것은, 오류가 불투명하면 사용자가 추측에 의존하게 된다는 사실을 보여 줍니다.
7. 빈 날짜 채우기 시계열
/api/v1/activity 엔드포인트는 요청한 범위의 모든 날짜를, 값이 0이더라도 전부 반환합니다. 프런트엔드가 빈칸을 채울 필요가 없고, 차트가 듬성듬성한 날짜 사이에서 튀지 않습니다. 작은 편의 기능이지만 사용 편의성에 주는 효과는 큽니다.
8. 헤더로 전달하는 요청 제한
모든 응답에 RateLimit-* 헤더가 붙어 있어서, 클라이언트는 429에 부딪히기 전에 속도를 줄일 수 있습니다. 이는 표준화된 IETF 초안 형식으로, GitHub 등 최신 API와 같은 형태입니다. 따라서 이 형식을 지원하는 기존 클라이언트 라이브러리는 별도 작업 없이 바로 동작합니다.
9. 읽기 전용 데이터에 대한 느슨한 CORS
읽기 전용 엔드포인트는 Access-Control-Allow-Origin: *을 보냅니다. 인증을 하는 것은 출처가 아니라 키이므로, CORS를 열어도 보안상 비용이 없고 브라우저 도구가 API를 직접 호출할 수 있습니다. 프록시 구성도, localhost 우회도 필요 없습니다.
10. 작고 안정적인 스키마
모든 응답은 화면 한 장에 들어갑니다. 선택적으로 중첩된 객체도, 기능 플래그가 켜져 있을 때만 나타나는 필드도 없습니다. 작은 스키마는 캐시하기 쉽고, 테스트하기 쉬우며, TypeScript 타입으로 쓰기도 편합니다.
실제 사용 예는 Server API 튜토리얼에서 볼 수 있습니다. 그리고 Discord 자체에 문제가 생겼을 때는 Discord API 오류가 실제로 무엇을 뜻하는지를 확인해 보세요.