アプリケーションプログラミングインタフェース

アプリケーションプログラミングインタフェースAPI: Application Programming Interface[1]とは、広義ではソフトウェアコンポーネント同士が互いに情報をやりとりするのに使用するインタフェースの仕様である。

APIには、サブルーチンデータ構造オブジェクトクラス、変数などの仕様が含まれる。APIには様々な形態があり、POSIXのような国際標準規格、マイクロソフトWindows APIのようなベンダーによる文書、プログラミング言語の標準ライブラリ(例えば、C++Standard Template LibraryJava APIなど)がある。

商業的に使われる狭義では、各種システムやサービス(ハードウェア、OSミドルウェアおよびWebサービス等)を利用するアプリケーションソフトウェア (Application) を開発・プログラミング (Programming) するためのインタフェース (Interface) である[2][3][4][5][6]。こちらの意味では、システムやサービスから直接提供されないもの、例えば言語の標準ライブラリは含まない。

APIはアプリケーションバイナリインタフェース (ABI) とは異なる。APIはソースコードベースだが、ABIはバイナリインタフェースである。例えば、POSIXはAPIだが、Linux Standard Base (LSB) はABIである[7](LSBはいろいろな規定の集合なので、正確には「LSBには、ABIにまで踏み込んでいる部分もある」)。

概要

広義のAPIでは単なるライブラリのインタフェースを含むかどうかにばらつきがあるなど定義が曖昧であるため、ここでは狭義のAPIについて説明する。

前述のとおりAPIは各種システム/サービスがそのシステム/サービスを利用するアプリケーションに対して公開するインタフェースである。APIの重要な役割は、システム/サービス提供者が公式に仕様(外部仕様)を定義し、管理している各種機能を利用するための操作方法(インタフェース)を提供することである。APIは多くの場合、アプリケーションを構築する言語と同じ言語のライブラリ、あるいは通信プロトコル形式[8]として提供され、システム/サービス開発者によって提供・管理される。

アプリケーションがシステム/サービスを利用するには、公開されたAPIを無視してシステム/サービスの現在の実装および内部仕様に依存した方法で利用できるケースもあるが、システム/サービス提供者はアプリケーションがAPI以外の仕様や実装に依存していることは関知せず、API以外の仕様や実装が永続的に維持されることも保証しない。バグ修正などで少しでもシステム/サービスの内部仕様に変更があれば、APIを利用しないアプリケーションはたちまち動かなくなってしまう。しかし、システム/サービスが更新されてもAPI外部仕様の後方互換性を維持したままである限りは、API仕様に則って開発されたアプリケーション側の変更は必要ない。アプリケーションがシステム/サービスを操作するにあたり、APIにだけ依存することでこのような互換性の問題を避けることができる。

隠しAPI

Microsoft WindowsmacOSiOSAndroidなどのOSには、外部に公開されているAPI以外に、俗に「隠しAPI」や「プライベートAPI」「非公開API」などと呼ばれるものが存在する。隠しAPIは特定の共通処理をアプリケーション側ではなくシステム内部でのみ再利用することを想定して実装されており、例えばWindowsでは一部の隠しAPI関数がシステムDLLにエクスポートされていることから、LoadLibrary関数を使用してAPI関数エントリポイントを動的ロードすることで呼び出すことができる。Java.NET Frameworkの場合は、カプセル化を破壊することになるが、隠蔽されたメソッドであってもリフレクションを使用して呼び出すことができる。しかし、これらはシステム/サービス提供者が公式に提供している機能ではなくAPIではない。このためこれらの隠し機能を使ったアプリケーションの動作は保証されないし、互換性も将来に渡って保証されることはない。例えばWindows APIにおいて、timeBeginPeriod(), timeEndPeriod()はアプリケーション開発者向けに正式公開・ドキュメント化されているAPI関数だが、これらは内部でNtSetTimerResolution()を呼び出している[9]NtSetTimerResolution()は、Windows NT系のシステムDLLのひとつ、"ntdll.dll"にエクスポートされているが、アプリケーション開発者向けのドキュメントには記載されていない隠し関数であり[10]、この隠し関数をアプリケーションで直接使用した場合の結果は保証されない。

ライブラリとAPI

APIは関数プロシージャ変数データ構造といったライブラリによって実装されることが多いが、狭義のAPIではライブラリとAPIは同一ではない。 ライブラリ形式ではなくプロトコル形式で提供される場合もあるという理由もあるが、ライブラリ形式である場合も同一視せず区別する必要があるという理由がある。

例えばAPIが関数であればサービスにより提供される関数はAPI関数と呼ぶが、API関数を利用して構築された関数はAPIではないためライブラリ関数と呼ぶ。 ライブラリ関数は直接サービスと関係ないか、APIを使って構築されておりサービスを利用する上で必須ではない。逆にAPI関数の存在はサービスを利用する上で必須である。例えばC言語の標準ライブラリ関数であるfwriteは、Windows上ではAPI関数であるWriteFileを使って実装されている。WriteFileはOSの機能に直接アクセスできることからfwriteよりも高機能であり、別OSへの移植性を考えなければfwriteの代わりにWriteFileを直接利用してアプリケーションを記述することもできる。同様に、Linuxではwriteシステムコールを利用して実装されている。

APIはサービスを利用するうえで必須になるが、APIを直接使用することは外部サービスに対する依存性を高め移植性を妨げる。例えば前述のWriteFileを使うプログラムは基本的にWindows用にしかコンパイルできないが、fwriteを使うプログラムはフリースタンディング環境以外ならどの環境でもコンパイルできる。このため移植性を考えるのであればAPIの直接使用は避け、APIを抽象化したライブラリを使用することが望ましい。 さらに、後述するように移植性を意識する言語ではライブラリとAPIを厳密に区別している場合が多い。特に後述のSmalltalkはクロスプラットフォームが一つの長所となっているためAPIの直接使用を避けることは重要となる。

C++の規格書では、API関数とライブラリ関数は一貫して区別されており、API関数は標準のライブラリ関数から呼び出されるもの、あるいは標準ライブラリの関数が同等の機能を模倣する対象として書かれている[11]。またCの規格書においてはAPIという言葉は無く、相当する関数がライブラリ関数以外の関数として書かれている[12]。1980年代から存在するSmalltalkでもAPIとライブラリは区別されており、例えばSmalltalk環境の一種であるPharoはAPIと対応しているパッケージをライブラリとは別にAPIとして区分している

なお、標準ライブラリはOSやファームウェアなどアプリケーション以外からも使われる。

詳細

ライブラリとフレームワーク

APIはソフトウェアライブラリと対応しているのが一般的である。 APIは「期待される挙動」を規定し説明するが、ライブラリはその規則群の「実際の実装」である。 1つのAPIが複数の実装を持つこともあるし、実装のない抽象的APIもありうる。

広義のAPIはソフトウェアフレームワークと対応する場合もある。フレームワークはいくつかのライブラリを備え、いくつかのAPIを実装することもあるが、通常のAPIとは使い方が異なり、「フレームワークに組み込まれた」挙動への「アクセス」としてフレームワーク自身に新たなクラスをプラグインすることでその内容を拡張するという手段をとる。さらに言えば、呼び出し側はプログラムの動作を制御できず、制御の反転や他の類似の機構によってフレームワーク側が流れを制御する[13]

APIとプロトコル

APIはプロトコルの実装となっていることもある。

プロトコルは、共通の転送手段に基づいた要求と応答の標準的交換方法を定義している。一方プロトコルを実装していないAPIは、ライブラリとして実装され、直接使われるのが一般的である。したがってAPIには「転送手段」が関与することはなく(遠隔のマシンとの物理的情報転送を行わない)、「関数呼び出し」によって単純に情報交換し、データは特定の言語で表現された形式で交換される[14]

APIがプロトコルの実装である場合、下層にある通信プロトコルを使ってリモート呼び出しを行うためのプロキシ的手段となっている。その場合のAPIの役目は、プロトコルの詳細を隠蔽することである。例えばJava RMIは、JRMPプロトコルまたはRMI-IIOPとしてのIIOPを実装している。

プロトコルは一般に異なるテクノロジー(特定OS内の特定プログラミング言語に基づくシステム)間をつなぎ、それらの間での情報交換を可能にしている。一方APIは特定のテクノロジーに固有であり、何らかの変換手段を用いない限り、ある言語用のAPIを別の言語では使用できない。

オブジェクトAPIとプロトコル

オブジェクトAPIは具体的なオブジェクト交換フォーマットを規定し、オブジェクト交換プロトコルはメッセージ内の同種の情報をリモートシステムに転送する方法を定義する。

2つの異なるプラットフォーム間で、両者にあるオブジェクトを使ってプロトコル経由でメッセージを交換する場合、あるプログラミング言語内のオブジェクトは相手の異なる言語でのオブジェクトに変換される。例えばJavaで書かれたプログラムがC#で書かれたサービスをSOAPIIOP経由で呼び出す場合、どちらのプログラムもリモート呼び出し用API(API自体はローカルに存在する)を使って情報交換し、ローカルなメモリ内でオブジェクトの変換を行う。

一方、同一マシン上でAPI経由のオブジェクト交換を行う場合、メモリ内で効率的に(オブジェクトまたはオブジェクトへの参照の)交換が行われる。例えば、1つのプロセスに割り当てられたメモリということもあるし、共有メモリを使って複数プロセス間で行うこともあるし、タプルスペースのような共有技法を使うこともある。

ウェブAPI

ウェブAPIはHTTP要求メッセージ定義とJSON形式等の応答メッセージ定義で構成される。Web 2.0ではSOAPベースからRESTベースへと変化している[15]。ウェブAPIはマッシュアップにより複数のサービスを組み合わせて新たなアプリケーションとすることを可能にする[16]

ウェブによるコンテンツ共有

APIを公表する慣習により、ウェブコミュニティにはコミュニティ間やアプリケーション間でコンテンツとデータを共有するオープンアーキテクチャが発展していった。そのため、ある場所で作成されたコンテンツはウェブ上の様々な場所で盛んにポストされ更新される。

  1. 写真はFlickrPhotobucketといったサイトからFacebookMyspaceといったソーシャルネットワークサイトに共有される。
  2. コンテンツは埋め込むこともできる。例えば、SlideShareにあるプレゼン資料をLinkedInのプロファイル情報に埋め込むことができる。
  3. TwitterのつぶやきをFacebookの投稿にも同時に反映させるAPIもある。
  4. 動画コンテンツも別のホスト上のサイトに埋め込むことができる。
  5. ウェブコミュニティにおけるユーザー情報を外部アプリケーションと共有させることができ、アプリケーションの更新をウェブ側から働きかけるなどの機能もオープンなAPIで実現されている。好例としてFacebookプラットフォームOpenSocialプラットフォームがある。

様式

WebAPIは様々なスタイルで表現される。例えばリソースの表現は以下の様式がありうる。

  • URLパス名: https://API.internal./japan/tokyo/sinjuku
  • URLクエリ文字列: https://API.internal./?country=japan&prefecture=tokyo&city=sinjuku
  • リクエストボディ: POST https://API.internal. Body {country: japan, prefecture: tokyo, city: sinjuku}

パスは厳密な階層構造をもつリソースの表現に適している。クエリ文字列およびリクエストボディは自由な表現が可能なため任意のリソースに利用できる。

広く知られるWebAPIスタイルの例として以下が挙げられる。

  • RESTful API: 操作をHTTPメソッド、リソースをURLパス名で表現
  • GraphQL: 操作およびリソースをリクエストボディ内にDSL (GraphQL query language) で表現
  • SOAP

実装

POSIX標準は、様々な一般的コンピューティング機能を各種システム上で実装できるよう考慮したAPIを定義している。例えば、macOSBSD系システムで実装されている。ただし、ABIや実行ファイル形式は標準化されていないため、POSIX準拠のプログラムを別のPOSIX準拠のプラットフォームで実行するには、再コンパイルが必要である。

一方、APIおよびABIに互換性があるシステムならば、どこでも同じバイナリをそのまま実行可能である。これはアプリケーションソフトウェアベンダーにもユーザーにも有益であり、ベンダーは互換API/ABIが実装されていれば新システムが登場してもアプリケーション製品を修正・リビルドせずに済むし、ユーザーも古いソフトウェアを後方互換性のある新システムにインストールして利用できる。ただし、それには一般に各種ライブラリが必要なAPI群を実装している必要がある。

WindowsはAPI/ABIに後方互換性があり、例えばVisual C++とWindows SDKを使用して開発されたアプリケーションは、ビルド時にWindows APIヘッダーをインクルードする前にWINVERおよび_WIN32_WINNTなどのシンボル[17]が適切に定義されていれば、指定したバージョン以降のすべてのWindowsで動作する[18]。廃止されたAPI関数などを使用していない限り、アプリケーションを修正・リビルドする必要はない。新しいバージョンのWindowsで追加された機能を使いたい場合、WINVERおよび_WIN32_WINNTをそのバージョンに合わせて定義するか、LoadLibrary関数を使用して動的ロードする。

なおWindows XP以降では、特定のバージョンのWindowsの実装や内部仕様に依存するなど、誤った実装や後方互換性を無視した実装により正常に動作しなくなってしまったアプリケーション向けに、「互換モード」が用意されている。これはシステム側が返す情報を特定バージョンのWindowsのものに偽装することで、アプリケーションをだますことにより動作させる救済措置であり[19][20][21]、本来はアプリケーション側をAPI外部仕様に基づいて正しく修正することが好ましい。

Unix系OSでは、相互に関連はあるが非互換なOS群が同一ハードウェア上で動作している。ソフトウェア業者が同一バイナリで各種OSに対応できるようAPIとABIを共通化する試みがなされてきたが、いずれも失敗に終わっている。そのような試みとしてLinuxではLinux Standard Baseがある。BSD系OSも各種あるが、互換性のレベルは様々である。

Androidには「APIレベル」という概念が存在し、Android OSのバージョンごとにAPIレベルの番号が割り振られている。例えばAndroid 10はAPIレベル29に相当する。特定のAPIレベルで追加された機能(クラス、メソッド、フィールド)を利用するには、アプリケーションのビルド時に "AndroidManifest.xml"[22] あるいは "build.gradle"[23] にてtargetSdkVersionの値をそのAPIレベル番号以降に設定し、また指定されたバージョン以降のAndroid SDKを使ってビルドする必要がある。また、minSdkVersionの値によって、アプリケーションのインストールおよび実行に必要な最小システムバージョンを指定することができる。minSdkVersion以下の機能は(廃止されたものでない限り)無条件で使用できるが、minSdkVersionを超えるバージョンで追加された機能を使用する場合は、android.os.Build.VERSIONクラスのSDK_INTフィールドの値に基づいて動的分岐する処理を実装する必要がある。

公開の方針

APIの公開に関しては2つの一般的な方針がある。

  1. 自社のAPIを厳重に秘匿する。
    例えばソニーライセンスをもった開発者にしかプレイステーションの公開APIを利用できないようにしている。なぜならプレイステーションのゲームを開発できる人の数を制限したほうが、より多くの利益をあげられるからである。これはAPIの実装を売ることで利益を上げるわけではない会社の典型的な例である。(ソニーの場合は、ゲーム開発時のAPIのライセンス料によって利益を上げようとしたがうまくいかず、プレイステーション用コンソールの販売を中止している。)
  2. 自社のAPIを広く普及させる。
    例えばマイクロソフトは計画的にAPIに関する情報を公開しているので、誰でも簡単にWindowsプラットフォーム用のソフトウェアを作成することができる。これはAPIの実装を販売して利益をあげる会社の例である。OSなどのAPIは、いくつかのコードに分割され、ライブラリとして実装されており、OSと一緒に配布される。OSと一緒に配布されるWindowsのAPIは誰でも使うことができる。また直接アプリケーションの中に統合される必要があるAPIもある。

この2つの方針の中間もある。

リバースエンジニアリングと著作権

互換性のためのAPIを作成するためにそのAPIの実装を解析することは一般的に合法である。この手法は相互運用性のためのリバースエンジニアリングと呼ばれる。しかしAPIそのものとは異なり、APIの実装には著作権が存在するため、リバースエンジニアリングする前には著作権侵害の問題が生じないよう、十分注意する必要がある。また、使おうとしているAPIに、特許保持者の許可がなければ使えない特許技術が許可なく含まれていたら、それは特許権侵害になりうる。(ただし、これはリバースエンジニアリングに限られた話ではなく、APIを利用するプログラムにも全般的に言えることである。)

2010年、米オラクルGoogleJavaの新たな実装をAndroidの一部として配布したとして、Googleを訴えた[24]。Java APIを複製する許可(ライセンス)はOpenJDKプロジェクトやIBM J9などの実装には与えられていたが、一方AndroidのDalvik仮想マシンの実装はOpenJDKなどに基づいてはおらず、またGoogleはJava APIを複製する許可をとっていなかった。これに対して、地方裁判所はAPIは著作権法の対象外であるとする判断を下したものの、控訴裁では保護対象であるとされ、最終的に2015年、最高裁によりアメリカ合衆国内ではAPIにも著作権があるとの判断が確定した[25][26][27]。ただし著作権があってもフェアユースの下に利用可能かについては、2015年現在継続して審理されている。

日本においては、著作権法第10条第3項において、プログラムのインタフェースやプロトコルが著作物とみなされないことが明確に示されている[28]

類似する概念

  • DDI (Device Driver Interface) - デバイスドライバーを開発するためのソフトウェアインタフェース。WindowsおよびLinuxの用語。
  • ファームウェアインタフェース - ファームウェアを開発するためのソフトウェアインタフェース。UEFI[29]など。
  • ASPI - SCSI 装置を制御するためのソフトウェアインタフェース

特にDDIやファームウェアインタフェースを使う場合は、ソフトウェアがアプリケーションと異なる環境で動作しAPIに依存するライブラリを使用できない場合があるため、開発者は自分が何を使っているか意識する必要がある。

APIの例

言語束縛とインタフェースジェネレータ

複数の高水準言語での使用を意図したAPIは、文法的・意味的に各言語に適したインタフェースをAPIに自動的にマッピングする機能を提供している。これを言語束縛と呼び、それ自体もAPIである。その目的は、そのAPIに要求される機能のほとんどをカプセル化するため、各言語に薄い層を設けることである。

以下に挙げたものは、コンパイル時に言語とAPIの束縛を行うインタフェースジェネレータである。

  • SWIG - オープンソースの多言語間のインタフェースジェネレータ(通常はC/C++からスクリプト言語へのインタフェースを生成)
  • F2PY:[30] - FortranからPythonへのインタフェースジェネレータ

脚注

  1. 「インターフェイス」「インターフェース」と表記されることもあるが、本記事では「インタフェース」で統一する。
  2. https://www.ibm.com/support/knowledgecenter/ja/SS4SVW_2.0.0/com.ibm.zosconnect.doc/backmatter/glossary.html#glossary__api
  3. https://developer.mozilla.org/ja/docs/Glossary/API
  4. http://www.ocn.ne.jp/support/words/abc/API.html%5B%5D
  5. https://www.synergy-marketing.co.jp/glossary/api/
  6. Smalltalk環境の提供元Cincomによる見積サービスの説明 APIの解説がある。
  7. Stoughton, Nick (2005年4月). Update on Standards (PDF)”. USENIX. 2009年6月4日閲覧。
  8. ローレベルなTCPあるいはUDPのパケット形式であったり、RESTSOAPに代表されるようなHTTPXMLなどを組み合わせた上位プロトコルであったりする。
  9. Sysinternals Freeware - Inside Windows NT High Resolution Timers
  10. NTAPI Undocumented Functions
  11. C++14の規格書の最終草案
  12. C11の規格書の最終草案
  13. Fowler, Martin. Inversion Of Control”. 2012年10月18日閲覧。
  14. API vs Protocol”. 2012年10月18日閲覧。
  15. Benslimane, Djamal; Schahram Dustdar, and Amit Sheth (2008年). Services Mashups: The New Generation of Web Applications”. IEEE Internet Computing, vol. 12, no. 5. Institute of Electrical and Electronics Engineers. pp. 13–15. 2012年10月18日閲覧。
  16. Niccolai, James (2008-04-23), “So What Is an Enterprise Mashup, Anyway?”, PC World, http://www.pcworld.com/businesscenter/article/145039/so_what_is_an_enterprise_mashup_anyway.html
  17. WINVER および _WIN32_WINNT の変更 | Microsoft Docs
  18. 新しいバージョンのコンパイラおよびWindows SDKでは、ある程度古いバージョンのWindowsのサポートが打ち切られることもある。
  19. 121ware.com > サービス&サポート > Q&A > 情報番号 003142
  20. Windows 7の互換機能を使いこなす(互換モード編) | 日経 xTECH(クロステック)
  21. Windows 8.1ミニTips(100) 「プログラム互換性アシスタント」を制御する●つの方法 | マイナビニュース
  22. <uses-sdk> | Android Developers
  23. ビルドを設定する | Android Developers
  24. Oracle and the End of Programming As We Know It”. DrDobbs (2012年5月1日). 2012年5月9日閲覧。
  25. Josh Lowensohn (2012年5月23日). Jury clears Google of infringing on Oracle's patents”. ZDNet. 2012年5月25日閲覧。
  26. Joe Mullin (2012年5月31日). Google wins crucial API ruling, Oracle’s case decimated”. Ars Technica. 2012年6月1日閲覧。
  27. 米最高裁がGoogleの訴えを却下、OracleとのJava著作権訴訟で”. ITPro (2015年6月30日). 2015年7月1日閲覧。
  28. 松下正. 知的財産権(特許・商標・著作権)の基礎講座”. 知的財産権(特許・商標・著作権)の基礎講座. 2015年7月1日閲覧。
  29. UEFI firmware requirements | Microsoft Docs
  30. F2PY.org”. F2PY.org. 2011年12月18日閲覧。

関連項目

外部リンク

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.