API Guidelines

外部APIと内部APIの両方を対象とする。 ウェブAPIは対象外。

一般性

  • 一般的な名前をつけてAPIの理解にかかる労力を名前への共通認識で軽減する。
  • 一般的でない名前はその差異の理解に労力を割かれる。
  • 実際に意味のある差異がある場合はこの限りではない。
append => add

対称性

  • 対称的なAPIには対称的な名前をつける。
  • 非対称のAPIに対称性の名前をつけない。
  • 非対称性がコンテキストから見て自然であるかモデルの制約である場合はこの限りではない。

対称性のAPIには対となるAPIも提供し、できない場合は対称性の名前をつけずなるべく非対称の名前をつける。 逆操作を行えないことに疑問を感じさせないようコンテキストとなるモジュールやオブジェクトの名前も含めて設計する。

append => append/prepend
append => add/remove
crypt => encrypt/decrypt
enqueue => queue

セマンティクス

  • 公開のAPIには意図の明白なセマンティックな名前をつける。
  • 非公開のAPIには意図より実際の動作を表した名前をつける。
  • 意図と実際の比重はAPIの公開範囲(規模)に比例する。

意図と実際を一致させるのは案外難しく、時間を置いて修正するとバグになりやすいため、 特に必要がない限り実際の動作をそのまま名前にして労力を節約する。

seal => lock
score => average

単一責任原則(SRP)

  • 接続詞を含む名前をつけない。
  • コンテキストを含む名前をつけない

SRPに反するAPIを作らない。 接続詞を含む名前はSRPに反しているか冗長である可能性が高い。 自身または中継するコンテキストを含まない名前をつける。 使用頻度が高く安定的なAPIであれば中継コンテキストを省略したAPIも適切であるが事前にそのようなAPIであるか判断することは困難。

callDogOrCat => callDog or callCat
sortByColumnNumber => sortBy(column: number) or sortByColumn(column: number)
addUserMailAddress => user.mail.add

パラメータ補完

  • APIに前置詞を用いる場合はAPI名の末尾に置いてパラメータとつなげて文を完成させる方法を検討する。

他のパラメータ用の常用APIを作る可能性がない場合はこれを選ぶ。 ある場合は前置詞の目的語をAPI名に含める。

sortByColumn => sortBy(column: number)

コンテキスト階層

  • 複数の名詞を含むAPIはコンテキストでAPIを階層化して名詞を分割する。
  • APIの一覧性やアクセシビリティを優先する場合は階層を結合する。
  • 階層化の程度は列挙による一覧性と集約による簡潔さおよびセマンティクスの兼ね合いで決める。

共有度が高く広範なコンテキストから順に階層化して内包する条件を分割する。 過度の階層化も過度の非階層化も等しくAPIの検索性とアクセシビリティを低下させるためAPIのボリュームと階層構造の把握しやすさから調整する。

addUserMailAddress => user.mail.add

フラクタル

  • 同種のAPIには同じパターンのAPIを反復する。
  • 同種のAPIには同じパターンでAPIを整列する。
  • 一般的な共通認識を変えてまでパターン化しない。

APIを相似形のパターンでフラクタル化することで知識と経験の再利用率を上げ学習コストを軽減する。 パターンの基準は独自定義からドメイン標準、言語設計に至るまで幅広く取ることができ、適用範囲もAPIの一部からプロダクトグループ全体まで及ぶ。 アプリケーションやウェブサイトのUIデザインでも非常に効果が高く常に推奨される。

user.mail.add/remove
user.family.child.add/remove