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

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

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

商業的に使われる狭義では、各種システムやサービスを利用するアプリケーションソフトウェア  を開発・プログラミング  するためのインタフェース  である。こちらの意味では、システムやサービスから直接提供されないもの、例えば言語の標準ライブラリは含まない。

APIはアプリケーションバイナリインタフェース  とは異なる。APIはソースコードベースだが、ABIはバイナリインタフェースである。例えば、POSIXはAPIだが、Linux Standard Base  はABIである。

1. 概要
-----

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

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

2. APIと非API
-----------

アプリケーションがシステム／サービスを利用するには、APIを無視してシステム／サービスの現在の実装および内部仕様に依存した方法がある。人と同じ操作をアプリケーションにさせたり、たまたま設定が書き込まれていたファイルをアプリケーションで読み取るなどである。この手法を非APIと言い英語圏ではnon-APIあるいはnon APIと呼ぶ。システム／サービス提供者はアプリケーションがAPI以外の仕様や実装に依存していることは関知せず、API以外の仕様や実装が永続的に維持されることも保証しない。このため非APIを使ったアプリケーションは、バグ修正などで少しでもシステム／サービスの内部仕様に変更があれば、たちまち動かなくなってしまう。この点、APIを使用する場合は、システム／サービスが更新されてもAPIが提供者によって後方互換性を維持してくれるため、アプリケーション側の変更は必要ない。アプリケーションがシステム／サービスを操作するにあたり、APIにだけ依存することでこのような互換性の問題を避けることができる。

ただし、APIを使う場合、APIの提供者から使用回数などに制限を掛けられる場合がありそれをらの制限を回避するためやAPIを提供していないシステム／サービスを使うために非APIを使う技術が重要になる場合もある。

2.1. ライブラリー形式の非API
------------------

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

2.2. ライブラリとAPI
--------------

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

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

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

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

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

3. 詳細
-----

3.1. ライブラリとフレームワーク
------------------

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

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

3.2. APIとプロトコル
--------------

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

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

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

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

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

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

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

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

4. ウェブAPI
---------

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

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

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

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

4.2. 様式
-------

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

URLパス名: ./japan/tokyo/sinjuku
URLクエリ文字列: ./?country=japan&prefecture=tokyo&city=sinjuku
リクエストボディ: POST . Body {country: japan, prefecture: tokyo, city: sinjuku}パスは厳密な階層構造をもつリソースの表現に適している。クエリ文字列およびリクエストボディは自由な表現が可能なため任意のリソースに利用できる。

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

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

5. 実装
-----

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

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

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

なおWindows XP以降では、特定のバージョンのWindowsの実装や内部仕様に依存するなど、誤った実装や後方互換性を無視した実装により正常に動作しなくなってしまったアプリケーション向けに、「互換モード」が用意されている。これはシステム側が返す情報を特定バージョンのWindowsのものに偽装することで、アプリケーションをだますことにより動作させる救済措置であり、本来はアプリケーション側を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"あるいは "build.gradle"にてtargetSdkVersionの値をそのAPIレベル番号以降に設定し、また指定されたバージョン以降のAndroid SDKを使ってビルドする必要がある。また、minSdkVersionの値によって、アプリケーションのインストールおよび実行に必要な最小システムバージョンを指定することができる。minSdkVersion以下の機能は無条件で使用できるが、minSdkVersionを超えるバージョンで追加された機能を使用する場合は、[7] クラスのSDK_INTフィールドの値に基づいて動的分岐する処理を実装する必要がある。

6. 公開の方針
--------

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

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

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

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

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

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

8. 類似する概念
---------

DDI  - デバイスドライバを開発するためのソフトウェアインタフェース。WindowsおよびLinuxの用語。
ファームウェアインタフェース - ファームウェアを開発するためのソフトウェアインタフェース。UEFIなど。
ASPI - SCSI 装置を制御するためのソフトウェアインタフェース特にDDIやファームウェアインタフェースを使う場合は、ソフトウェアがアプリケーションと異なる環境で動作しAPIに依存するライブラリを使用できない場合があるため、開発者は自分が何を使っているか意識する必要がある。

9. APIの例
--------

CarbonとCocoa - macOS
CORBA
Document Object Model  - HTML文書やXML文書をアプリケーションから利用するためのAPI
DirectX - Microsoft Windows用のマルチメディアAPI
EHLLAPI
iconv - 文字コード間の相互変換用API
I/O Kit - Darwin
ODBC - Microsoft Windows
OpenAL - クロスプラットフォームのオーディオAPI
OpenCL - 異種計算資源を汎用並列処理に使用するためのクロスプラットフォームのAPI
OpenGL - クロスプラットフォームのグラフィックスAPI
OpenMP - クロスプラットフォームの共有メモリ型マルチプロセッシング用API。C/C++、Fortranで利用可能。
POSIX
QuickTime
Single UNIX Specification
Simple DirectMedia Layer 
Toolbox - Mac OS
Windows API - Microsoft Windows
XPCOM
[8]- EDIを組み込めるAPI
[9]- 画像加工API

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

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

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

SWIG - オープンソースの多言語間のインタフェースジェネレータ
F2PY: - FortranからPythonへのインタフェースジェネレータ

11. 脚注
------

11.1. 注釈
--------

11.2. 出典
--------

12. 関連項目
--------

システムコール
呼出規約
Foreign function interface
名前修飾
プラグイン
ソフトウェア開発キット

13. 外部リンク
---------