1. ホーム
  2. rest

[解決済み】RESTful APIで多対多の関係を処理するにはどうすればよいですか?

2022-03-27 20:35:19

質問

2つのエンティティがあるとします。 プレイヤー チーム であり、プレーヤーは複数のチームに所属することができます。 データモデルでは、各エンティティに対応するテーブルと、リレーションシップを維持するためのジョインテーブルがあります。 ハイバーネート はこの処理に適していますが、このリレーションを RESTful APIは?

いくつかの方法が考えられます。 たとえば、Playerオブジェクトは所属するチームのリストを持ち、各Teamオブジェクトは所属するPlayerのリストを持つようにします。 したがって、あるチームにプレーヤーを追加するには、次のようにします。 POST のようなエンドポイントに、プレーヤーの表現をPOST /player またはPOST /team を、適切なオブジェクトをリクエストのペイロードとして指定します。 これが最もRESTfulな方法だと思いますが、少し変な感じがします。

/api/team/0:

{
    name: 'Boston Celtics',
    logo: '/img/Celtics.png',
    players: [
        '/api/player/20',
        '/api/player/5',
        '/api/player/34'
    ]
}

/api/player/20:

{
    pk: 20,
    name: 'Ray Allen',
    birth: '1975-07-20T02:00:00Z',
    team: '/api/team/0'
}

もう一つの方法は、リレーションシップをそれ自身のリソースとして公開することです。 つまり、あるチームの全選手のリストを見るには、GET を実行します。 /playerteam/team/{id} のようなもので、PlayerTeamエンティティのリストが返されます。 プレーヤーをチームに追加するには、POST /playerteam を、適切に構築された PlayerTeam エンティティをペイロードとして指定します。

/api/team/0:

{
    name: 'Boston Celtics',
    logo: '/img/Celtics.png'
}

/api/player/20:

{
    pk: 20,
    name: 'Ray Allen',
    birth: '1975-07-20T02:00:00Z',
    team: '/api/team/0'
}

/api/player/team/0/:

[
    '/api/player/20',
    '/api/player/5',
    '/api/player/34'
]

そのためのベストプラクティスは何でしょうか?

どのように解決するのですか?

RESTfulインターフェースでは、リソース間の関係をリンクとして符号化することで、その関係を記述したドキュメントを返すことができます。したがって、あるチームは、ドキュメント・リソース( /team/{id}/players ) へのリンクのリストであり、選手 ( /player/{id} )があり、プレーヤーはドキュメント・リソース( /player/{id}/teams ) は、そのプレーヤーが所属しているチームへのリンクのリストである。対称的で良いですね。このリストに対してマップ操作を行うのは簡単で、リレーションシップに独自のIDを与えることもできます(チーム優先のリレーションシップかプレイヤー優先のリレーションシップかによって、2つのIDを持つことは間違いないでしょう)。唯一の厄介な点は、一方からリレーションシップを削除した場合、もう一方からも削除することを忘れないようにしなければならないことです。しかし、基盤となるデータモデルを使用し、RESTインターフェースをそのモデルのビューにすることによって、これを厳密に処理すれば、より簡単になるでしょう。

リレーションシップIDは、チームや選手に使用するIDの種類に関係なく、おそらくUUIDか、同じように長くてランダムなものをベースにする必要があります。そうすれば、リレーションシップの両端のIDコンポーネントとして、衝突を心配することなく同じUUIDを使用できます(小さな整数が有効です)。 ない はそのような利点があります)。これらのメンバーシップ・リレーションシップが、プレーヤーとチームを双方向に関連付けるという事実以外に何らかの特性を持つ場合、プレーヤーとチームの両方から独立した独自のIDを持つべきです。プレーヤー」チーム・ビューのGET ( /player/{playerID}/teams/{teamID} ) にHTTPリダイレクトすることができます。 /memberships/{uuid} ).

もし、あなたがXMLを作成するのであれば、XML文書にリンクを書くことをお勧めします。 XLink xlink:href 属性があります。