t0mmy

2020年12月30日に参加

学習履歴詳細

APIデザインパターン 6章 リソース識別子 読了

やったこと

  • APIデザインパターン 6章 リソース識別子 読了

学んだこと

ポイント

  • 良い識別子が満たすべき属性
  • 良い識別子とは
  • 識別子を実装する際の勘所

学び

  • 良い識別子が満たすべき属性は、大きく7つある
  • 上記属性を満たしたうえで、良い識別子の条件がいくつか存在する
  • 識別子の生成に、Base32エンコーディングは有効
  • UUIDは2005年7月には仕様が策定されている
  • UUIDは万能ではない

メモ

識別子とは

APIにおいて、特定のリソースを一意に識別するための値。

良い識別子が満たすべき属性

  1. 使いやすい事
    • RESTなどで簡単に扱うことが出来ること(記号を含まないことなど)
  2. 一意であること
  3. 不変であること
  4. 高速で簡単に生成できること
  5. 他人が予測不可能であること
  6. 読みやすく、共有しやすく、検証可能であること
    • アナログな方法でやり取りする可能性を考慮し、不必要に難しくしないこと
    • チェックサムを導入して、識別子の誤りを検出できること
  7. 情報密度が高いこと
    • 小さいサイズで、できるだけ多くの情報を詰め込むこと

良い識別子とは

  • データ型は文字列を推奨
    • 汎用性が高く、プログラムやUIからも扱いやすい
    • URL中で使用することを考慮し、'/'などURLで意味のある文字は含めないことを推奨
    • ASCIIで構成するのが最も安全
  • ASCIIの中でも、記号や誤解を招きやすい文字(IとL、Oと0など)は除外するのが無難
    • Base32エンコードすると、簡単に解決できる
  • 使われていない識別子と、明らかに誤っている識別子を区別できる
    • チェックサムを用いることで、「明らかに誤っている識別子」を検出できる
  • リソースの種類が一目でわかる
    • book/識別子のように、識別子の前にリソースの名前を持ってくると良い
    • book/識別子/page/識別子のように、階層構造を構築する戦略もある
      • 以下のような場合に、うまく適応する
        • リソースが親子関係でる
        • 子要素だけでは成り立たない
      • そうではない場合、将来階層構造の変更を試みる時に識別子の不変性要件を満たせなくなる
        • shelves/識別子book/識別子など
        • bookリソースのプロパティに、本棚の識別子を持たせた方が合理的

実装の勘所

  • 識別子の長さは固定にすると良い
  • 識別子は疑似乱数生成器 & Base32 などで生成する
    • 利用者側で生成させてはならない
      • 機微な情報を含めてしまう、予測不可能ではなくなってしまうなど、弊害が多い
  • 「生成した識別子が、既に生成されていないか」を検証できるようにする
    • データを削除する際、論理削除を用いる
      • データが増えると、計算時間が増えてしまう問題を抱える
    • 衝突が考えられないほど、長い識別子を使用する
      • UUIDはこの戦略
  • チェックサムはDBに保存するべきではない
    • チェックサムの計算アルゴリズムを後から変更できる
  • 識別子をDBに保存する場合の戦略
    • 基本は文字列、文字列が不可能な場合はバイトで格納する
    • 識別子には、情報密度が最大となる「2のN乗」となるような長さを選択する

UUIDは万能ではない

UUIDは、良い識別子が満たすべき属性を満たしている。
しかし、常にUUIDを使えばよいというわけではない。

UUIDは、以下の点で万能ではない。

  • 一般的なユースケースではオーバースペックになりがち
  • (Base32と比較して)情報密度が低い
    • Base32は1文字列に5ビット詰め込めるのに対して、UUIDは1文字に4ビットまで
  • 定義上、チェックサムを持っていない
    • 使われていない識別子と、明らかに誤っている識別子を明確に区別できない

それでも、多くのユースケースにおいて、UUIDは優れた選択肢である。


扱うこと

  • 識別子とは何か
  • 良い識別子の持つ属性
  • 良い識別子とは何か
  • 識別子を作成するシステムはどのように実装するか
  • 本章の内容とUUID

まとめ

  • 識別子は、APIにおいて、特定のリソースを一意に識別するための値
  • 良い識別子は使いやすく、一意性をもち、値が不変で、素早く簡単に生成でき、予測不可能で、読みやすく、コピー可能で、共有可能で、情報量が多いもの
  • 識別子はASCII文字セットで構成された文字列であるべき
    • 利用者が扱いやすい
  • 識別子は、チェックサム文字を使用して、以下を区別できる必要がある
    • 存在しないリソース
    • リソースを指していない識別子
WebAPI

2023年06月03日(土)

1.0時間