편안한 서비스로 정렬 된 목록 리소스를 어떻게 디자인해야합니까?


11

나는이 같은 문제를 반복해서 겪었고 실제로 최적이라고 느낀 해결책을 찾지 못했습니다.

앱에서 순서 목록이 있으며 사용자가 끌어서 놓기 등으로 순서를 변경할 수 있습니다. 순서대로 변경 사항을 유지하려고합니다. 어떻게 모델링합니까?

정렬 된 목록 리소스의 편안한 서비스를 어떻게 디자인해야합니까?

특히, 편안한 자원의 모델 listitem모델을 어떻게 설계해야 합니까? 내가 본 가장 일반적인 디자인 itemorder또는 position속성을 가진 엔터티 입니다. 내가 들었던 또 다른 접근법은 항목에 이중으로 연결된 목록입니다.

데이터베이스에 너무 많이 쓰지 않고 일반적으로 클라이언트에 대한 업데이트 및 읽기 속도가 빠른 방법은 무엇입니까? 엔드 포인트는 어떻게 노출되어야합니까?


호기심 때문에 주문 목록을 구체적으로 반환하는 것이 왜 중요합니까?
Adam Wells

글쎄, 나는 특별히 정렬 된 목록 리소스를 반환하려고하지는 않지만 실제 목록 리소스의 일부이거나 암시 적으로 목록의 일부일 수있는 리소스의 순서 / 위치를 유지합니다. 나는 사용자가 할 일 목록에서 할 일의 순서를 변경하도록 허용하고 싶다. 그러나 주문이 중요한 목록이 여전히 무엇이든 상관 없습니다. 내가 찾을 수없는 것은 이것을 디자인하는 좋은 방법입니다.
Rico Kahler

답변:


14

정렬 된 목록을 나타내는 것은 관계형 데이터베이스의 어려운 문제 중 하나입니다. 목록 멤버쉽 관계에 위치 특성을 추가하는 것이 가장 일반적인 방법입니다. ORDER BY positionSQL 쿼리 에 추가하여 정렬 된 목록을 쉽게 검색 할 수 있고 평균을 계산하여 목록 중간에 항목을 쉽게 삽입 할 수 있기 때문입니다. 위치가 정수가 아니라 부동 소수점이라고 가정하고 이전 및 후속 목록 멤버의 값

실수로 링크를 일관성있게 만들지 않고 대신 순환 그래프 나 트리로 끝나기 때문에 이중 링크리스트를 사용하지 않아야합니다.

그러나 RESTful API에는 관계형 데이터베이스의 제한이 없습니다. 위치 속성과 같은 핵을 사용하는 대신 자연스러운 느낌을 줄 수 있습니다.

목록에 최대 수백 개의 요소 만있는 경우 요청에서 전체 목록을 전송하십시오. [1, 2, 3, 4]리스트 멤버가 ID 인 곳 을 재정렬하고 싶다고 가정하면

POST /url/of/the/list
Content-type: application/json
...

[1, 2, 4, 3]

그러면 백엔드는이를 사용중인 데이터베이스 기술로 변환 할 수 있지만 API 사용자는 이러한 세부 사항을 고려할 필요가 없습니다.

목록이 크고 항목이 일반적으로 개별적으로 요청되는 경우 url에 색인을 허용 할 수 있습니다.

GET /page/7

HATEOAS를 사용하는 경우 리소스가 일반적으로 그렇게 소비되는 경우 응답에 이전 / 다음 링크가 포함되어 탐색을 간단하게 만들 수 있습니다. 그러나 데이터베이스에이 이중 연결 목록도 포함되어 있다는 의미는 아닙니다.

목록이 매우 큰 경우 또는 / ArrayList와 같은 유사한 작업 을 노출 할 수 있습니다 . 나는 같은 전화를 상상할 수 있었다insertpushappend

POST /url/of/the/list?at=1357;mode=insert
...

description of the item to insert

재정렬이 일반적인 사용 사례이고 재정렬이 즉시 커밋되어야하는 경우 API에서 적절한 엔드 포인트를 제공 할 수 있습니다.

POST /url/of/the/list/reorder-item?from=783;to=1357

재정렬 된 목록을 명시 적으로 커밋해야하는 경우 새 주문을 JSON 문서로 이전하는 것이 더 쉽습니다 (위 참조).

이제 API를 사용중인 데이터베이스 기술과 완전히 분리 된 것으로 볼 수있는 것은 사실이 아닙니다. 그러나 구현 세부 사항에서 가능한 한 외부 API를 최대한 유지하는 것이 가장 좋습니다. 정수 순서 열을 업데이트하기 위해 재정렬이 약 30 행에 닿아도 큰 문제는 아닙니다. 가능한 가장 간단한 일을하고 항상 전체 목록을 업데이트하십시오. 규모에 따라 데이터베이스를보다 정교하게 사용해야하는 경우 백엔드에서 이러한 정교성을 캡처하여 일관성을 유지하기가 더 쉽습니다.


1
여러 클라이언트가 변경하는 경우 "전체 목록 바꾸기"방법이 문제가 될 수 있습니다. 예방 조치를 취하지 않으면 다른 사람의 변경 사항을 덮어 쓰게 될 수 있습니다 ( "마지막으로 쓰기").
oefe 2016 년

매개 변수 (at, from, to)가 인덱스가 아닌 id 인 경우리스트와 유사한 연산에는이 문제가
없어야

2

다른 접근 방식의 실행 가능성은 사용중인 기본 데이터베이스에 크게 의존한다고 생각합니다.

이 접근 방식은 주문에서 항목을 이동하도록 제안했습니다.

POST / url / of / the / list / reorder-item? from = 783; to = 1357

SERIALIZABLE 거래가 없으면 경쟁 조건이 적용될 수 있습니다. 대부분의 DB에서 기본 수준 인 READ_COMMITTED는 경쟁 조건을 제거하지 않습니다!

필자는 실제로 목록이 상대적으로 작은 한 대부분의 경우 교체 전체 목록 접근 방식은 경쟁 조건과 관련된 문제가 적고 데이터를 손상시킬 수 없다고 생각합니다. 클라이언트가 요청한 후 항목 세트가 변경된 경우 409 (충돌)를 리턴 할 수 있습니다.

마지막 쓰기 성공으로 어려움을 겪지 만 말 그대로 모든 API에 해당됩니다. 어떤 API를 구현하든 다른 클라이언트가 페이지를 보는 동안 해당 내용을 업데이트했을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.