覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

API提供時に気を付けること

アプリケーションが第三者向けにインターフェース(API)を提供する場合に、考慮すべきだが抜け落ちてしまう可能性があるものを記載しました

  • 提供すべきAPI自体がどうあるべきか? と API利用者にドキュメントや補足説明で何を伝えるべきか? を記載しています
  • 記載した内容は私の経験によるものです
  • 記載した内容のベースはJavaです
  • システムやソフトウェアのコンテキストによって当てはまるものもあれば当てはまらないものもあります


APIと呼ぶべきものの候補

そもそも、どういったものがAPIとなるのか?例えば以下のようなものなどがAPIとなりうる

  • クラス
  • メソッド(関数)
  • ファイル(とその中のデータ)
  • ネットワークを介した電文(メッセージ)
  • MQの電文
  • etc…


API利用者向けに公開すべき情報

APIを提供する場合には以下に記載した内容を、仕様として明確にして利用者に伝えた方がよい(以下の内容はドキュメント等に書いてあった方がよいし、たとえばJavaならjavadoc等に書いてあるとなおさら良い)

  • パラメータ

    • 必須項目が何か
    • パラメータの型が何か
    • パラメータの値範囲(境界値を含んでいいのか、含んで指定はダメなのか を明記する)
    • パラメータのフォーマット(例:yyyy/MM/dd …etc)
    • パラメータの組み合わせの制限
    • パラメータに対する変更操作(パラメータの内容を変更してしまう)が発生する場合は明記する
    • パラメータの形式(JSON, XML, …etc)
  • 戻り値(応答内容)

    • 特殊ケースの戻り値(例:検索結果が0件の場合に空Listを返す ということ)も明記する
    • 戻り値の形式(JSON, XML, …etc)
  • エラーケース時の動作

    • 業務的なエラーケース時の動作
    • 不正なパラメータを与えたときの動作
  • ユースケースごとの実行例(サンプル)

    • ユースケースごとのAPIの利用方法を記載する
    • 基本的に利用者はサンプルをコピーして使用する傾向にある。サンプルが多くあればあるほど、利用する際の最初の敷居が下がる
  • 利用者側のAPIに関する責任

    • 例えばopen(のAPI)を実行したら必ず利用側の責任でcloseを呼ぶ必要があることなどを明記する
  • 並列実行時の動作

    • 並列実行を許可しているか、いないか
    • 並列実行するとシーケンシャルに実行されるのかパラレルに実行されるのか
  • 依存する環境

    • 対象APIが(そのシステムやソフトウェアの)バージョンいくつから利用できるのか?
    • 他のシステムと連携して提供する機能であれば、その他システムがバージョンいくつ以上でないといけないか?等を明記する
  • プロトコル

    • AMQP, HTTP(HTTPS), ・・・
      • HTTPならメソッドは GET/POST/PUT/DELETE のいずれであるかの情報も載せた方が良い
  • 互換性

    • APIのバージョンによって利用者が受ける結果(アウトプット)が異なる場合、バージョン間での動作の差異を明記する


APIそのものが考慮すべき点

  • 対象APIを実行した際に無限待ちが発生しないか?
    • (無限)待ちの可能性があるなら必ずタイムアウトを発生させるように考慮する
  • 対象APIをクラス+メソッドの形で提供するなら、APIの実装クラスはスレッドセーフであることが望ましい
    • 実装クラスがスレッドセーフなら、API利用者は毎回APIクラスのインスタンスをnewしなくて済む。
  • 対象APIをクラス+メソッドの形で提供する場合、パラメータ(引数)はImmutableであることが望ましい
    • Immutableでない場合APIの処理中に、外部からパラメータの内容を書き換えられてしまう危険性がある
  • 対象APIの引数や戻り値等で大量データを取り扱った場合にメモリ不足のエラー等にならないか?
  • APIのバックエンドにあるアーキテクチャを表に出さないようにする
    • 例えばURLの中に “Servlet” や “.php” という単語が入っていたりするとバックエンドのプログラム言語が何か分かってしまう
    • 例えばAPIから返されるエラーの内容に “ORA-XXXX” という文字が入っていると、バックエンドにOracleが存在することがわかる
    • 利用者はバックエンドのアーキテクチャに興味は無いし、publicに公開されるようなAPIでバックエンドのアーキテクチャが分かると攻撃の対象になってしまう
  • APIの戻り値(レスポンス)でバックエンドのDBのテーブル構造をそのまま返さない
    • APIはアプリケーションのインターフェースであって、データベースのアクセスインターフェースではない
    • アプリケーションの特性を踏まえた、利用者が使いやすいデータ構造を返すように検討すべきである


さらに留意すべき事項

  • そもそもAPI利用者が間違った使い方ができないようにするのが理想的
  • APIを実行する順序の制限は極力ない方が扱いやすい
  • API側でパラメータに対する変更操作(副作用)を発生させるのは極力避ける
  • 利用者はクラスやメソッドの集合には関心は無い。自分のやりたいこと(ユースケース)がどのようにしたら実現できるかに関心がある
  • 利用するAPIとAPIの拡張を可能とする部分(SPI)を同じ場所(同じパッケージ等)に配置しない。配置すると利用者などが混乱する
  • 同一のAPIを連続で実行された場合に冪とう性があるか?
  • API利用までの初期化手順(セットアップ手順)は極力少なくなるようにする
  • APIの"プログラム"と"ドキュメント"の間で、内容に差異が無いようにする。(プログラムを修正したら必ずドキュメントにも反映する