sourcetip

여러 고유 ID를 사용한 Rest API 설계

fileupload 2023. 2. 17. 21:34
반응형

여러 고유 ID를 사용한 Rest API 설계

현재 시스템용 API를 개발하고 있으며 식별자가 다를 수 있는 리소스가 있습니다.를 들어, '먹다'라는 .orders아이디입니다.는 「」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」 「URL」

GET /api/orders/{id}
PUT /api/orders/{id}
DELETE /api/orders/{id}

그러나 지금은 주문번호를 사용할 수도 있어야 합니다.그 결과 보통 다음과 같은 결과가 됩니다.

GET /api/orders/{orderNumber}
PUT /api/orders/{orderNumber}
DELETE /api/orders/{orderNumber}

id와 order Number는 둘 다 숫자이기 때문에 이 방법은 분명 작동하지 않습니다.

비슷한 질문이 몇 가지 있다는 것은 알지만, 답변이 잘 맞지 않거나 그 접근법이 별로 안정적이지 않거나 이해하기 어렵기 때문에 도움이 되지 않습니다(저희와 API를 사용하는 개발자들에게).또한 질문과 답변은 부분적으로 7년 이상 전의 것입니다.

몇 가지 예를 들자면:

1. 쿼리 파라미터의 사용

예를 들어 쿼리 매개 변수를 사용할 것을 제안합니다.

GET /api/orders/?orderNumber={orderNumber}

러러가가가가문문문문문요요요요요요요요 。먼저, 이것은 주문 컬렉션에 대한 필터이므로 결과도 목록이 되어야 합니다.단, 주문번호는 1개뿐이어서 조금 헷갈립니다.둘째, 이러한 필터를 사용하여 주문의 서브셋을 검색/필터링합니다.또한 쿼리 파라미터는 일종의 세컨드 클래스 파라미터이지만 이 경우 퍼스트 클래스여야 합니다.오브젝트가 존재하지 않는 경우에도 문제가 됩니다.수 없음)를하지만 get 404(「」)는 반환됩니다.GET /api/orders/?orderNumber=1234순서 1234가 존재하지 않는 경우 빈 배열이 됩니다.

2. 프레픽스 사용

일부 공용 API는 다음과 같은 여러 유형을 구별하기 위해 일종의 식별자를 사용합니다.

GET /api/orders/id_1234
GET /api/orders/ordernumber_367652

접근법에 가 있다. , 그것은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.왜냐하면id_1234 ★★★★★★★★★★★★★★★★★」ordernumber_367652다른 리소스에서도 반환되는 실제 고유 식별자입니다.할 수 있습니다. " , 으면 안 된다.

{
  "id": "id_1234",
  "ordernumber": "ordernumber_367652"
  //...
}

유형(ID 또는 주문 번호)이 두 번 모형화되기 때문에 그다지 깨끗하지 않습니다.또, 모든 식별자와 응답 오브젝트를 변경하는 문제와는 별도로, 예를 들면 67363보다 큰 모든 주문 번호를 검색하는 경우(따라서 문자열과 번호의 충돌도 발생합니다).응답에 의해 타입이 프리픽스로 추가되지 않는 경우는, 유저는 몇개의 요구에 대해서 이 타입을 추가할 필요가 있습니다.이것은 매우 혼란스러울 수 있습니다(이것을 추가할 필요가 있는 경우와 그렇지 않은 경우가 있습니다).

3. 동사의 사용

예를 들어 다음과 같습니다.은 Twitter: URL로 .show.json을 사용하다

GET /api/orders/show.json?id=1234 
GET /api/orders/show.json?number=367652

나는 이것이 가장 끔찍한 해결책이라고 생각한다. 왜냐하면 그것은 안정적이지 않기 때문이다.또한 쿼리 파라미터 접근법에서 언급한 몇 가지 문제가 있습니다.

4. 서브리소스의 사용

일부 사용자는 이를 하위 리소스와 같이 모델링할 것을 제안합니다. 예를 들어 다음과 같습니다.

GET /api/orders/1234 
GET /api/orders/id/1234   //optional
GET /api/orders/ordernumber/367652

쉽다고 만, 「가독성」의 는, 「가독성」이라고 합니다./api/orders/ordernumber/367652"주문번호 367652를 취득합니다."가 아니라 "주문번호 367652를 취득하십시오."어느 정도라고 은 여러 가지 좋은 점만 사용하고 자원만 모범 입니다.마지막으로, 이는 여러 가지 사용 및 실제 리소스만 사용하는 것과 같은 몇 가지 모범 사례를 위반합니다.

마지막으로, 제 질문은 다음과 같습니다. 우리가 뭘 놓쳤나요?또 다른 접근법이 있을까요?그것은 드문 문제가 아니라고 생각하기 때문입니다.

나에게 당신의 문제를 해결하는 가장 쉬운 방법은 2번 접근 방식을 약간 수정하는 것입니다.

이론적 관점에서 보면 주문을 식별하기 위한 유효한 식별 코드를 가지고 있을 뿐입니다.설계 프로세스의 이 시점에서 식별 코드가 ID인지 주문 번호인지는 중요하지 않습니다.주문을 고유하게 식별할 수 있는 것으로 충분합니다.

ID 형식과 숫자 형식이 모호하다는 것은 설계 단계가 아니라 구현 단계에 속하는 문제입니다.

지금으로서는, 다음과 같이 되어 있습니다.

GET /api/orders/{some_identification_code}

그리고 이것은 매우 편안합니다.

물론 아직 애매한 부분을 해결해야 하는 문제가 있기 때문에 구현 단계를 진행할 수 있습니다.도 주문하셨습니다.identification_code세트는 형식을 공유하는 두 개의 개별 엔티티로 구성됩니다.그것이 작동하지 않는 것은 사소한 일이다.그러나 현재 문제는 이러한 엔티티 형식의 정의에 있습니다.

제안사항은 매우 간단합니다.ID는 정수, 번호는 N1234567 등의 코드입니다.이 방법을 사용하면 리소스 표현이 허용됩니다.

{
  "id": "1234",
  "ordernumber": "N367652"
  //...
}

또한 택배 발송 등 많은 시나리오에서 일반적입니다.

여기 제가 조금 더 입맛에 맞는 다른 옵션이 있습니다.

GET /api/orders/1234
GET /api/orders/1234?idType=id //optional
GET /api/orders/367652?idType=ordernumber

그 이유는 패싱이 REST 표준과 일관되게 유지되기 때문입니다.또, 패싱이 idType=orderNumber(디폴트로는 idType)를 통과했을 경우는, 그 패싱을 선택할 수 있습니다.

저는 같은 문제로 고민하고 있고, 아직 완벽한 해결책을 찾지 못했습니다.결국 다음 형식을 사용하게 되었습니다.

GET /api/orders/{orderid}
GET /api/orders/bynumber/{orderNumber}

완벽하진 않지만 읽을 만해요.

나도 힘들어!저 같은 경우에는 세컨더리 ID를 사용하여 GET만 하면 되기 때문에 조금 더 쉬워집니다.

ID에 옵션 접두사를 사용할 수 있습니다.

GET /api/orders/{id}
GET /api/orders/id:{id}
GET /api/orders/number:{orderNumber}

또는 URI 사양의 불분명한 기능인 경로 파라미터를 사용하여 특정 경로 요소에 파라미터를 부가할 수 있습니다.

GET /api/orders/{id}
GET /api/orders/{id};id_type=id
GET /api/orders/{orderNumber};id_type=number

정규화되지 않은 ID를 사용하는 URL이 표준 URL입니다.비표준 URL 동작에는 엔티티를 반환하거나 표준 URL로 리디렉션하는 두 가지 옵션이 있습니다.후자는 이론적으로는 순수하지만 사용자에게 불편할 수 있습니다.혹은, 유저에게 있어서 편리할 수도 있습니다.

또 다른 방법은 주문번호를 독자적인 것으로 모델링하는 것입니다.

GET /api/ordernumbers/{orderNumber}

이렇게 하면 ID만 있는 작은 개체가 반환될 수 있으며 사용자는 이를 사용하여 엔티티를 검색할 수 있습니다.또는 주문으로 리다이렉트 할 수도 있습니다.

일반 검색 리소스도 사용할 수 있습니다.

GET /api/orders?number={orderNumber}

저 같은 경우에는 아직 그런 리소스가 필요 없고 하나의 필드만 지원하는 일반적인 검색 리소스를 추가하는 것이 불편할 수 있습니다.

따라서 기본적으로 모든 ID와 주문 번호를 주문 레코드의 고유 식별자로 취급해야 합니다.고유 식별자는 고유해야 합니다!하지만 ID와 주문번호는 모두 숫자입니다.범위가 겹치나요?예를 들어 "1234"가 ID 또는 주문 번호일 경우, 당연히 /api/orders/1234는 고유한 주문을 참조하지 않습니다.

범위가 고유할 경우 /api/orders/{id} 핸들러 코드에 ID와 주문 번호를 구분할 수 있는 식별자 논리만 있으면 됩니다.예를 들어 주문번호가 ID보다 더 많은 숫자를 가지고 있는 경우 이 방법은 실제로 작동할 수 있습니다.하지만 할 수 있었다면 이미 해냈을 거라고 생각해요

범위가 중복될 수 있는 경우 최소한 해당 범위에 대한 참조를 고유 범위로 설정해야 합니다.가장 간단한 방법은 주문번호를 참조할 때 접두사(예: 접두사 "N")를 추가하는 것입니다.따라서 ID가 1234인 주문에 주문번호가 367652인 경우 다음 중 하나의 호출로 검색할 수 있습니다.

/api/orders/1234
/api/orders/N367652

단, 모든 순서 번호에 "N" 프리픽스를 포함하도록 데이터베이스를 변경하거나(이러한 경우는 불가능하다고 합니다), 핸들러 코드는 int로 변환하기 전에 "N" 프리픽스를 삭제해야 합니다.이 경우 "N" 접두사는 API 호출에서만 사용해야 합니다. 사용자 대면 데이터 입력 양식에서 N 접두사를 노출하면 안 됩니다.사용자가 ID 또는 주문 번호를 입력할 수 있는 "식별 검색" 필드는 사용할 수 없습니다(어차피 고유하지 않은 문제가 발생합니다).대신 "id로 검색" 및 "주문 번호로 검색" 옵션이 별도로 있어야 합니다.그런 다음 API에 제출하기 전에 주문 번호 입력 핸들러가 "N" 접두사를 자동으로 추가하도록 할 수 있습니다.

기본적으로 이것은 데이터베이스 설계에 관한 문제입니다.이것이 (양쪽 필드의 값을 '고유 식별자'로 사용) 요건이라면 데이터베이스 필드는 이를 염두에 두고 설계되어야 합니다(즉, 오버랩되지 않는 범위).순서 번호 형식을 변경할 수 없는 경우에는 ID 형식이 달라야 합니다.

언급URL : https://stackoverflow.com/questions/41103091/rest-api-design-with-multiple-unique-ids

반응형