安らかなサービスで順序付きリストリソースを設計するにはどうすればよいですか?


11

私はこの同じ問題に何度も遭遇しましたが、私が本当に最適だと感じた解決策は見つかりませんでした。

アプリで言うと、順序付けられたリストがあり、ユーザーがドラッグアンドドロップなどでその順序を変更できるようにします。順序の変更を保持したい場合。どのようにモデル化しますか?

順序付きリストリソースの安らかなサービスを設計するにはどうすればよいですか?

具体的には、どのように私が設計する必要がありますlistし、item安らかなリソースのモデルを?私が見た最も一般的なデザインは、またはプロパティitemを持つエンティティです。私が聞いた別のアプローチは、アイテムの二重リンクリストです。orderposition

データベースへの書き込みが多すぎず、クライアントの更新と読み取りが一般に高速なアプローチとは何ですか?エンドポイントはどのように公開されるべきですか?


好奇心から、特別に順序付きリストを返すことが重要なのはなぜですか?
アダムウェルズ

まあ、私は特別に順序付きリストリソースを返すのではなく、実際のリストリソースの一部または暗黙的にリストの一部にできるリソースの順序/位置を保持するだけだと思います。ユーザーがtodoのリストでtodoの順序を変更できるようにしたい。しかし、順序が重要なリストがまだ存在していても関係ありません。私が見つけられないのは、これを設計する良い方法です
リコカーラー

回答:


14

順序付きリストを表すことは、リレーショナルデータベースの難しい問題の1つです。位置プロパティをリストメンバーシップリレーションに追加するのが最も一般的な方法ですORDER BY position。SQLクエリに追加することで順序付きリストを簡単に取得でき、平均化することでリストの中央にアイテムを簡単に挿入できるからです。位置が整数ではなく浮動小数点であると仮定して、前および後のリストメンバーの値。

誤ってリンクを矛盾させてしまい、代わりに周期的なグラフやツリーができてしまうので、二重にリンクされたリストの使用は避けるべきです。

ただし、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を使用している場合、リソースが通常そのように消費される場合、ナビゲーションに簡単にするために、応答にprev / nextリンクを含めることができます。ただし、データベースにこの二重リンクリストも含まれていることを示す必要はありません。

リストが非常に大きい場合、または/ 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

パラメーター(at、from、to)がリストインデックスではなくIDである場合、リストのような操作ではこの問題は発生しません
oefe

2

さまざまなアプローチの実行可能性は、使用されている基礎となるデータベースに大きく依存すると思います。

このアプローチは、順序でアイテムを移動することを提案しました。

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

シリアライズ可能なトランザクション性がない限り、競合状態になる可能性があります。ほとんどのDBのREAD_COMMITTEDのデフォルトレベルでは、競合状態は解消されません。

リストが比較的小さい限り、ほとんどの場合、リスト全体を置換するアプローチでは競合状態の問題が少なく、データを破損できないと実際に考えています。クライアントがリクエストを行ってからアイテムのセットが変更された場合、409(競合)を返すことができます。

それは最後の書き込みの勝利に苦しんでいますが、それは文字通りどんなAPIにも当てはまります。実装しているAPIに関係なく、ページを表示している間に別のクライアントが更新した可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.