識別子はとても奥が深かった
概要
APIデザイン・パターン という本に、識別子に関する章(6章)がありました。
この章では、識別子について詳しく解説しており、非常に多くの学びがありました。
この記事では、そんな自分が得た学びを共有します。
識別子とは
APIにおいては、特定のリソースを一意に識別するための値。
本記事(というか本家「APIデザイン・パターン」)では特に、WebAPI における識別子に焦点を当てている。
IDの方が馴染み深いかも。
良い識別子が満たすべき属性
良い識別子とは、以下7つの属性を満たしたもの。
- 使いやすいこと
- 一意であること
- 不変であること
- 高速で簡単に生成できること
- 他人が予測不可能であること
- 読みやすく、共有しやすく、検証可能であること
- 情報密度が高いこと
- 小さなサイズで、できるだけ多くの情報密度を詰め込みことができること
ちょっと抽象的な「使いやすいこと」「不変であること」「読みやすく、共有しやすく、検証可能であること」は、もう少し掘り下げる。
「使いやすいこと」とは
本記事がWebAPIに焦点を当てていることを念頭に置くと、特にURIとしての扱いやすさが重要。
反対に、扱いにくい識別子の例には、以下が挙げられる。
- URIとして意味のある記号(
/
など)を含んでしまっていること- エンコーディングが必要
「不変であること」とは
システム存命中、識別子が指し示すリソースが、変化しないこと。
反対に、「識別子が指し示すリソースが、変化する」ような事態は、リソースを削除した後の識別子を使いまわす といった行為で発生する。
「読みやすく、共有しやすく、検証可能であること」とは
「読みやすく、共有しやすい」とは
識別子をアナログな手段(口頭伝達や紙媒体のメモなど)で伝達することを想定している。
具体的な手段には、以下が挙げられる。
- 誤解を招きやすい文字(Iとlと1、Oと0など)の使用を避ける
- 補足が不要な分、共有しやすい
- 読み手も、「この文字はIとlのどっち?」と混乱することがなくなり、読みやすくなる
- 情報密度が高いこと
- 文字数が少なければ、それだけ早く共有できるようになる
「検証可能であること」とは
識別子が破損していないか検証可能であること。
言い換えると、無効な識別子かどうか判別できること。
- 識別子の破損は、特にアナログな手段での伝達で発生しやすい
具体的な手段には、以下が挙げられる。
- チェックサムの導入
より良い識別子を実装する勘所
上記「良い識別子が満たすべき属性」を満たした上で、以下の勘所を押さえることで、より良い識別子となる。
- データ型は文字列を推奨
- 汎用性が高く、プログラムやUIからも扱いやすい
- URL中で使用することを考慮し、'/'などURLで意味のある文字は含めないことを推奨
- ASCIIで構成するのが最も安全
- ASCIIの中でも、記号や誤解を招きやすい文字(IとL、Oと0など)は除外するのが無難
- Base32エンコードすると、簡単に解決できる
- 使われていない識別子と、明らかに誤っている識別子を区別できる
- チェックサムを用いることで、「明らかに誤っている識別子」を検出できる
- リソースの種類が一目でわかる
-
book/識別子
のように、識別子の前にリソースの名前を持ってくると良い
-
UUID は万能ではない
UUIDは、「良い識別子が満たすべき属性」の多くを満たしている。
しかし、常にUUIDを使えばよいというわけではない。
UUIDは、以下の点で万能ではない。
- 一般的なユースケースではオーバースペックになりがち
- (Base32と比較して)情報密度が低い
- Base32は1文字列に5ビット詰め込めるのに対して、UUIDは1文字に4ビットまで
- 定義上、チェックサムを持っていない
- 使われていない識別子と、明らかに誤っている識別子を明確に区別できない
上記問題点が許容できない場合は、UUIDは使えない。
それでも、多くのユースケースにおいて、UUIDは優れた選択肢となる。
所感
識別子について深く考えたことがなかったため、「識別子はここまで考えることが色々あるのか」と、読んでいて非常に学びが多い章でした。
特に、以下の場面で活躍しそうだな、と思っています。
- UUIDを使用するべきか、使用するべきではないか、の判断
- 識別子を自作するとき
「識別子はこんなに奥が深いのか」と、少しでも学びの一助になれば幸いです。
より詳しく知りたい方は、本家「APIデザイン・パターン」を当たることをお勧めします。
Discussion