데이터 모델이 안정화 되기 시작했으며 웹 앱용 공개 API를 만들 수 있는 위치에 있습니다. API가 출시 된 후에는 API를 크게 변경하는 것이 어렵다는 것을 깨닫고 가능한 한 많은 부분을 바로 잡기를 원합니다.
이제 인터넷은 API 디자인에 대한 의견이 부족하지 않습니다. 그러나 모든 경우에 작동하는 널리 채택 된 표준은 없기 때문에 선택의 여지가 있습니다. 어떤 형식을 허용해야 합니까? 어떻게 인증해야 합니까? API의 버전을 관리해야 합니까?
Enchant 용 API (Zendesk 대안)를 설계 할 때 이러한 질문에 대한 실용적인 답을 찾으려고 노력했습니다. 제 목표는 Enchant API가 사용하기 쉽고 채택하기 쉬우며 자체 사용자 인터페이스에 대해 dogfood 할 수 있을 만큼 유연해지는 것입니다.
https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
TL;DR
API에 대한 주요 요구 사항
웹에서 발견되는 많은 API 디자인 의견은 실제 세계에서 의미가 있는 것과는 반대로 퍼지 표준에 대한 주관적인 해석을 중심으로 하는 학문적 토론입니다. 이 게시물의 목표는 오늘날의 웹 애플리케이션을 위해 설계된 실용적인 API의 모범 사례를 설명하는 것입니다. 옳지 않다고 생각되면 기준을 만족 시키려고 하지 않습니다. 의사 결정 프로세스를 안내하기 위해 API가 추구해야 하는 몇 가지 요구 사항을 적어 두었습니다.
API는 개발자의 UI입니다. 모든 UI와 마찬가지로 사용자의 경험을 신중하게 고려하는 것이 중요합니다!
RESTful URL 및 작업 사용
널리 채택 된 것이 하나 있다면 RESTful 원칙입니다. 이것들은 네트워크 기반 소프트웨어 아키텍처에 대한 그의 논문 5 장에서 Roy Fielding에 의해 처음 소개되었습니다.
REST의 핵심 원칙은 API를 논리적 리소스로 분리하는 것입니다. 이러한 리소스는 메서드 (GET, POST, PUT, PATCH, DELETE)에 특정 의미가 있는 HTTP 요청을 사용하여 조작됩니다.
그러나 내가 자원을 만들 수 있습니까? 음, 이것들은 동사가 아니라 API 소비자의 관점에서 의미가 있는 명사여야 합니다. 명확하게 말하면, 명사는 사물이고 동사는 당신이 그것에 하는 일입니다. Enchant의 명사 중 일부는 ticket, user 및 customer입니다.
주의 : 내부 모델이 리소스에 깔끔하게 매핑될 수 있지만 반드시 일대일 매핑은 아닙니다. 여기서 핵심은 API에 관련 없는 구현 세부 정보를 유출하지 않는 것입니다! API 리소스는 API 소비자의 관점에서 이해할 수 있어야 합니다.
리소스를 정의한 후에는 해당 리소스에 적용되는 작업과 해당 작업이 API에 매핑 되는 방식을 식별해야 합니다. RESTful 원칙은 다음과 같이 매핑 된 HTTP 메서드를 사용하여 CRUD 작업을 처리하는 전략을 제공합니다.
REST의 가장 큰 장점은 기존 HTTP 메서드를 활용하여 단일 / tickets 엔드 포인트에서만 중요한 기능을 구현한다는 것입니다. 따라야 할 메서드 명명 규칙이 없으며 URL 구조가 깨끗하고 명확합니다. 휴식 FTW!
끝점 이름은 단수 또는 복수여야 합니까? 여기에는 단순 유지 규칙이 적용됩니다. 내부 문법가는 복수형을 사용하여 리소스의 단일 인스턴스를 설명하는 것이 잘못되었다고 말할 수 있지만 실용적인 대답은 URL 형식을 일관되게 유지하고 항상 복수형을 사용하는 것입니다. 이상한 복수형 (person / people, goose / geese)을 처리 할 필요가 없어 API 소비자의 삶이 더 좋아지고 API 공급자가 구현하기가 더 쉽습니다 (대부분의 최신 프레임 워크는 기본적으로 /tickets 및 /tickets/12를 공통 컨트롤러).
그러나 관계를 어떻게 처리합니까? 관계가 다른 리소스 내에서만 존재할 수 있는 경우 RESTful 원칙은 유용한 지침을 제공합니다. 예를 들어 살펴 보겠습니다. Enchant의 티켓은 여러 메시지로 구성됩니다. 이러한 메시지는 다음과 같이 /tickets 엔드 포인트에 논리적으로 매핑될 수 있습니다.
대안 1 : 관계가 리소스와 독립적으로 존재할 수 있는 경우 리소스의 출력 표현 내에 관계에 대한 식별자를 포함하는 것이 합리적입니다. 그런 다음 API 소비자는 관계의 끝점에 도달해야 합니다.
대안 2 : 독립적으로 존재하는 관계가 리소스와 함께 일반적으로 요청되는 경우 API는 관계의 표현을 자동으로 포함하고 API에 대한 두 번째 적중을 방지하는 기능을 제공 할 수 있습니다. 깨끗한 API와 서버에 대한 하나의 히트. 나는 이 접근 방식을 좋아합니다.
CRUD 작업의 세계에 맞지 않는 작업은 어떻습니까?
이것은 일이 모호해질 수 있는 곳입니다. 여러 가지 접근 방식이 있습니다.
어디서나 SSL-항상
항상 SSL을 사용하십시오. 예외 없음. 오늘날 웹 API는 인터넷이 있는 모든 곳 (예 : 도서관, 커피 숍, 공항 등)에서 액세스 할 수 있습니다. 이 모든 것이 안전하지는 않습니다. 대부분은 통신을 전혀 암호화하지 않으므로 인증 자격 증명이 도용 된 경우 쉽게 도청하거나 가장 할 수 있습니다.
항상 SSL을 사용하는 또 다른 장점은 보장 된 암호화 된 통신이 인증 노력을 단순화한다는 것입니다. 각 API 요청에 서명 할 필요 없이 간단한 액세스 토큰을 사용하면 됩니다.
주의해야 할 사항은 API URL에 대한 비 SSL 액세스입니다. 이들을 SSL 대응 물로 리디렉션 하지 마십시오. 대신 하드 오류를 던지십시오! 자동 리디렉션이 설정되면 잘못 구성된 클라이언트가 무의식적으로 암호화되지 않은 엔드 포인트를 통해 요청 매개 변수를 유출 할 수 있습니다. 하드 오류는 이 실수를 조기에 발견하고 클라이언트가 올바르게 구성되도록 합니다.
문서
API는 문서만큼이나 좋습니다. 문서는 찾기 쉽고 공개적으로 액세스 할 수 있어야 합니다. 대부분의 개발자는 통합 작업을 시도하기 전에 문서를 확인합니다. 문서가 PDF 파일에 숨겨져 있거나 로그인이 필요한 경우 찾기가 어려울 뿐만 아니라 검색하기도 쉽지 않습니다.
문서는 완전한 요청 / 응답주기의 예를 보여야 합니다. 요청은 브라우저에 붙여 넣을 수 있는 링크 또는 터미널에 붙여 넣을 수 있는 curl 예제와 같이 붙여 넣을 수 있는 예제여야 합니다. GitHub와 Stripe는 이것으로 훌륭한 일을 합니다.
공개 API를 출시하면 예고 없이 작업을 중단하지 않기로 약속 한 것입니다. 문서에는 지원 중단 일정과 외부에서 볼 수 있는 API 업데이트와 관련된 세부 정보가 포함되어야 합니다. 업데이트는 블로그 (예 : 변경 로그) 또는 메일 링리스트 (바람직 하게는 둘 다!)를 통해 전달되어야 합니다.
버전 관리
항상 API 버전을 지정하십시오. 버전 관리를 사용하면 더 빠르게 반복하고 잘못된 요청이 업데이트 된 엔드 포인트에 도달하지 않도록 방지 할 수 있습니다. 또한 일정 기간 동안 이전 API 버전을 계속 제공 할 수 있으므로 모든 주요 API 버전 전환을 원활하게 수행 할 수 있습니다.
API 버전이 URL에 포함되어야 하는지 헤더에 포함되어야 하는지에 대해 의견이 분분합니다. 학문적으로 말하면 아마도 헤더에 있어야 합니다. 그러나 버전 간 리소스의 브라우저 탐색 가능성을 보장하고 (이 게시물 상단에 지정된 API 요구 사항을 기억하십니까?) 더 간단한 개발자 경험을 가지려면 버전이 URL에 있어야 합니다.
저는 Stripe가 API 버전 관리에 대해 취한 접근 방식을 좋아합니다. URL에는 주 버전 번호 (v1)가 있지만 API에는 사용자 지정 HTTP 요청 헤더를 사용하여 선택할 수 있는 날짜 기반 하위 버전이 있습니다. 이 경우 주 버전은 API 전체의 구조적 안정성을 제공하는 반면 하위 버전은 작은 변경 (필드 사용 중단, 엔드 포인트 변경 등)을 설명합니다.
API는 완전히 안정적 일 수 없습니다. 변화는 불가피합니다. 중요한 것은 그 변화를 관리하는 방법입니다. 잘 문서화되고 발표 된 여러 달의 지원 중단 일정은 많은 API에서 허용되는 관행 일 수 있습니다. 업계와 API의 가능한 소비자를 고려할 때 합리적입니다.
결과 필터링, 정렬 및 검색
기본 리소스 URL은 최대한 간결하게 유지하는 것이 가장 좋습니다. 복잡한 결과 필터, 정렬 요구 사항 및 고급 검색 (단일 유형의 리소스로 제한되는 경우)은 모두 기본 URL 위에 쿼리 매개 변수로 쉽게 구현할 수 있습니다. 더 자세히 살펴 보겠습니다.
필터링 : 필터링을 구현하는 각 필드에 고유 한 쿼리 매개 변수를 사용합니다. 예를 들어 / tickets 엔드 포인트에서 티켓 목록을 요청할 때 이러한 티켓을 열린 상태의 티켓으로 만 제한 할 수 있습니다. 이는 GET / tickets? state = open과 같은 요청으로 수행 할 수 있습니다. 여기서 state는 필터를 구현하는 쿼리 매개 변수입니다.
정렬 : 필터링과 유사하게 일반 매개 변수 정렬을 사용하여 정렬 규칙을 설명 할 수 있습니다. 정렬 매개 변수가 쉼표로 구분 된 필드 목록을 가져 오도록하여 복잡한 정렬 요구 사항을 수용하십시오. 몇 가지 예를 살펴 보겠습니다.
검색 : 때때로 기본 필터로는 충분하지 않으며 전체 텍스트 검색 기능이 필요합니다. 이미 ElasticSearch 또는 다른 Lucene 기반 검색 기술을 사용하고 있을 수 있습니다. 전체 텍스트 검색이 특정 유형의 리소스에 대한 리소스 인스턴스를 검색하는 메커니즘으로 사용되는 경우 API에서 리소스 끝점의 쿼리 매개 변수로 노출 될 수 있습니다. q라고 합시다. 검색 쿼리는 검색 엔진에 직접 전달되어야 하며 API 출력은 일반 목록 결과와 동일한 형식이어야 합니다.
이들을 결합하여 다음과 같은 쿼리를 작성할 수 있습니다.
일반적인 쿼리에 대한 별칭
일반 소비자가 API 경험을 보다 즐겁게 만들려면 조건 세트를 쉽게 액세스 할 수 있는 RESTful 경로로 패키징 하는 것이 좋습니다. 예를 들어, 위의 최근 마감 티켓 쿼리는 GET / tickets / recently_closed로 패키징 될 수 있습니다.
API에서 반환하는 필드 제한
API 소비자가 항상 리소스의 전체 표현을 필요로 하는 것은 아닙니다. 반환 된 필드를 선택하고 선택할 수 있는 기능은 API 소비자가 네트워크 트래픽을 최소화하고 API 사용 속도를 높이는 데 큰 도움이 됩니다.
포함 할 쉼표로 구분 된 필드 목록을 사용하는 fields 쿼리 매개 변수를 사용합니다. 예를 들어 다음 요청은 정렬 된 열린 티켓 목록을 표시하기에 충분한 정보 만 검색합니다.
GET /tickets?fields=id,subject,updated_at&state=open&sort=-updated_at
참고 :이 접근 방식은 관련 리소스의 자동로드와 결합 될 수도 있습니다.
GET /tickets?embed=customer&fields=id,customer.id,customer.name
업데이트 및 생성은 리소스 표현을 반환해야 합니다.
PUT, POST 또는 PATCH 호출은 제공된 매개 변수의 일부가 아닌 기본 리소스의 필드를 수정할 수 있습니다 (예 : created_at 또는 updated_at 타임 스탬프). API 소비자가 업데이트 된 표현을 위해 API에 다시 접속하지 않도록 하려면 API가 업데이트 된 (또는 생성 된) 표현을 응답의 일부로 반환하도록 합니다.
생성 된 POST의 경우 HTTP 201 상태 코드를 사용하고 새 리소스의 URL을 가리키는 Location 헤더를 포함합니다. 두 가지 모두 새로 생성 된 리소스 표현을 응답 본문으로 포함해야 합니다.
Authentication
RESTful API는 상태 비 저장이어야 합니다. 이것은 요청 인증이 쿠키나 세션에 의존해서는 안된다는 것을 의미합니다. 대신 각 요청은 일종의 인증 자격 증명과 함께 제공되어야 합니다.
항상 SSL을 사용하면 HTTP 기본 인증의 사용자 이름 필드에 전달되는 임의로 생성 된 액세스 토큰으로 인증 자격 증명을 단순화 할 수 있습니다. 이것에 대한 가장 좋은 점은 브라우저가 완전히 탐색 할 수 있다는 것입니다. 브라우저는 서버에서 401 Unauthorized 상태 코드를 수신하면 자격 증명을 묻는 메시지를 표시합니다.
그러나 기본 인증을 통한 토큰 인증 방법은 사용자가 관리 인터페이스에서 API 소비자 환경으로 토큰을 복사하도록 하는 것이 실용적인 경우에만 허용됩니다. 이것이 불가능한 경우 OAuth 2를 사용하여 제 3 자에게 안전한 토큰 전송을 제공해야 합니다. OAuth 2는 Bearer 토큰을 사용하며 기본 전송 암호화를 위해 SSL에 의존합니다.
JSONP 요청은 HTTP 기본 인증 자격 증명 또는 Bearer 토큰을 보낼 수 없으므로 JSONP를 지원해야 하는 API에는 세 번째 인증 방법이 필요합니다. 이 경우 특수 쿼리 매개 변수 access_token을 사용할 수 있습니다. 참고 : 대부분의 웹 서버는 서버 로그에 쿼리 매개 변수를 저장하기 때문에 토큰에 쿼리 매개 변수를 사용하는 데 고유 한 보안 문제가 있습니다.
그만한 가치는 위의 세 가지 방법 모두 API 경계를 통해 토큰을 전송하는 방법일 뿐입니다. 실제 기본 토큰 자체는 동일 할 수 있습니다.
요약
API는 개발자를 위한 사용자 인터페이스입니다. 기능적 일 뿐만 아니라 사용하기 쾌적하도록 노력하십시오.
등록된 댓글이 없습니다.