programing

REST-가능한 여러 식별자 지원

nicescript 2021. 1. 16. 09:19
반응형

REST-가능한 여러 식별자 지원


내가 작업중인 사이트의 경우 한 가지 유형의 리소스에 대한 URL을 개선하는 중입니다. 특히 숫자 ID에서 고유 한 설명 문자열로 이동하는 것입니다. 유사한 예는 숫자 데이터베이스 ID로 사용자를 식별하는 것에서 사용자 이름으로 식별하는 것으로 전환하는 것입니다 (특정 사례가 아니라 분석). 따라서 사용자 정보에 액세스하기위한 URL은 다음과 같습니다.

/users/48573

그리고 지금은

/users/thisisausername.

유일한 문제는 API의 레거시 소비자를 위해 어떻게 든 숫자 ID를 통해 가져올 수 있어야한다는 것입니다. 리디렉션 할 REST URL 자체는 필요하지 않습니다 (예 :로 리디렉션 /users/48573해서는 안 됨 /users/thisisausername). 이전 식별자를 사용하여 올바른 데이터를 얻는 방법 만 있으면됩니다. 솔루션은 ID로 사용자 정보 (편리하게 새 식별자, 사용자 이름 포함)에 액세스하거나 ID로 사용자 이름에만 액세스하는 대체 방법을 제공해야합니다. 가능한 솔루션은 다음과 같습니다.

  • 노드를 사용하여 다른 식별 방법을 지정합니다. 예 : /users/byid/48573
  • 쿼리 매개 변수를 사용하여 다른 식별 방법을 지정합니다. 예 : /users/48573?fetchby=id또는/users/48573?byid=true
  • ID 별 사용자 이름을 다른 리소스로 취급, 예 : /identifiers/username/48573

다음 중 적절한 REST에 가장 가까운 것은 무엇입니까? 문제를 어떻게 처리 하시겠습니까?


경로 세그먼트 / 접두사를 추가하는 것이 가장 좋은 대답이라고 생각합니다. 이들은 고유 한 보조 키이므로 검색 (항목 집합을 반환)과 동일하지 않으므로 쿼리 매개 변수 (캐시되지 않음)를 사용하는 것이 최선의 선택이 아닌 것 같습니다.

개인적으로 "name ="또는 "email ="과 같이 "="로 구분 된 경로 세그먼트 접두사를 사용할 계획입니다.

user/123456
user/name=john.doe
user/email=john.doe@john.doe

이것은 기능적으로 경로 세그먼트 (예 : "user / name / john.doe")를 추가하는 것과 동일하지만 개념적 모델에 더 가깝게 매핑되는 것처럼 느껴집니다. 물론 RESTful API는 고정 된 URI 구조를 지정해서는 안되기 때문에 이것은 중요하지 않은 세부 사항입니다.

쿼리 매개 변수를 사용하지 않으면 하위 리소스에 자연스럽게 액세스 할 수 있습니다.

user/name=john.doe/inbox/df87bhJXrg63

Java의 JAX-RS와 같은 프레임 워크는 원하는 구분 기호를 사용하여 지원합니다.

@GET
@Path("user/{id}")
User getUser(@PathParam("id") UUID id);

@GET
@Path("user/name={name}")
User getUserByName(@PathParam("name") String name);

@GET
@Path("user/email={email}")
User getUserByEmail(@PathParam("email") String email);

첫 번째 옵션이 아마도 가장 좋습니다.

ID로 사용자 검색 :

/users/id/48573

짧은 이름으로 사용자 검색 :

/users/name/thisisausername

경로 매개 변수를 생략하면 항상 새로운 짧은 사용자 이름 형식을 기본값으로 사용할 수 있습니다.

내가 꽤 많이 본 또 다른 옵션은 다음과 같은 쿼리 매개 변수를 사용하는 것입니다.

/users?id=48573
/users?name=thisisausername

나는 첫 번째가 조금 더 깨끗하고 읽기 쉬워 보인다고 생각합니다.


꽤 오래된 질문이지만 똑같고 마침내 해결책을 찾았습니다 : 경로 매개 변수에 정규식을 사용하십시오.

이 사용 사례를 코딩 한 방법은 다음과 같습니다.

@GET
@Path("/{id : \\d+}")
@Produces(APPLICATION_JSON)
public Response getById(@PathParam("id") long id) {
 <<your code>>
}

@GET
@Path("/{name}")
@Produces(APPLICATION_JSON)
public Response getByName(@PathParam("name") String name) {
 <<your code>>
}

이것이 문제라면 API는 RESTful이 아닙니다. Roy Fielding 인용 하려면 :

A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations. [Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC's functional coupling].

A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]


I'd consider qualifying the string with an optional suffix:

/users/48573/id

/users/48573/name

If you receive a string without the suffix:

/users/48573

then you check the string and see if it's an ID or Name.

If you only get a valid ID but not a name then it's a retrieval by ID equivalent to:

/users/48573/id

If you only get a name back then it's a retrieval by Name equivalent to:

/users/48573/name

If you can retrieve the value by ID or Name then you return a 300 response error and return links to both possiblities to the client:

/users/48573/id

/users/48573/name

The legacy consumers continue to work 'as is' except for the occasional occurence of duplicate ID/name pairs where they receive the new 300 response error.

ReferenceURL : https://stackoverflow.com/questions/842261/rest-supporting-multiple-possible-identifiers

반응형