Open3
API設計のTIPS

APIのパスに/admin/のようなroleを含めるべきか
- 一般的には含めずに認証ヘッダに含まれるJWTにroleを含めて識別すべき
- しかし 、/admin/のようなpathを含めることで middlewareレベルで統一した挙動を実現できる
- ただし、同一リソースに対してさまざまなロールによるアクセスレベルが存在する場合、ロールごとにパスを作成するのは大変になる
- 前提として、role制御はscopeによる認可制御よりも粒度が粗いことは理解しておく
結論
jwtのroleによる認可をシステムの前提としつつ、利便性のために採用するのはあり。
ただし、adminやanonなど、極端なroleぐらいしか採用できない。これらはセキュリティ的に特別扱いするのは全然OKだし、その労力に見合う対価はありそう。

/parents/:parentId/children/:childId
のような親子リソースをAPIのパスで表現すべきかどうか?
-
childId
がグローバルユニークかどうかによる。グローバルユニークでなければparentsId
が必須になる。 - もし仮に childIdが グローバルユニークであるとき、技術的には
children/:childId
というAPI設計は可能- 本当は親子関係だけど、利便性やセキュリティのため、公開用idとして自然PKとは別にユニークidをもっているパターン
- 何も考えずにとりあえず、サロゲートkeyをすべてのリソースで採用しているパターン
- 真に親子関係かどうかを考えるには、親リソースを削除したときに、子リソースが独立して生存可能かどうかを考えれば良い
- childIdがその公開idであれば、そもそもURLの短縮が目的なので素直に
children/:childId
とすればよい - マルチテナント型のサービスの場合、多くは parentsIdはテナントidを示す。
- この場合、基本的に
/parents/:parentId
をAPIに含めた方が良い。- middlewareレベルで、childrenリソースがparentIdに属するものか検証しやすい
- middlewareレベルで、リクエストアカウントがparentIdに属するか検証できる
結論
- テナントリソースかグローバルリソースかを意識する
- 将来のシャーディング(DB分割)を踏まえて、基本的に自然PKを採用する
- セキュリティ的にリソースidを隠したい、URLを短くしたいなどのニーズがある場合、自然PKとは別に公開idを用意する
- 公開idは将来シャーディングしにくいリスクがあることを承知する
- リソースを扱うAPIは基本的に自然PKをAPIで表現する
- マルチテナント型のサービスの場合、
- 基本的には
/tenants/:tenantId/
をprefixとしてAPIに設定しておいたほうが、セキュリティを検証しやすい - リソースのネストが深くなってしまう場合(親 > 子 > 孫)、孫リソースを直接tenantIdの子として移動できないか考える(親 > (子、孫))。子(孫から見た直接の親)をPKとしてもたずFKとする。
- 基本的には

/resources/:resourceId
とするか/resources?resourceId=:resorceId
とするべきか
単一のリソースを指定するとき、結論
- クエリは配列が返ってくる前提なので、単一のリソースはPKのidを指定する。これは複合PKの場合も同様