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

概要

広義のAPIでは単なるライブラリのインタフェースを含むかどうかにばらつきがあるなど定義が曖昧であるため、ここでは狭義のAPIについて説明する。
前述のとおりAPIは各種システム／サービスがそのシステム／サービスを利用するアプリケーションに対して公開するインタフェースである。APIの重要な役割は、システム／サービス提供者が公式に仕様（外部仕様）を定義し管理している各種機能を利用するための操作方法（インタフェース）を提供することである。APIは多くの場合、アプリケーションを構築する言語と同じ言語のライブラリ、あるいは通信プロトコル形式として提供され、システム／サービス開発者によって提供・管理される。
アプリケーションがシステム／サービスを利用するには、公開されたAPIを無視してシステム／サービスの現在の実装および内部仕様に依存した方法で利用できるケースもあるが、システム／サービス提供者はアプリケーションがAPI以外の仕様や実装に依存していることは関知せず、API以外の仕様や実装が永続的に維持されることも保証しない。バグ修正などで少しでもシステム／サービスの内部仕様に変更があれば、APIを利用しないアプリケーションはたちまち動かなくなってしまう。しかし、システム／サービスが更新されてもAPI外部仕様の後方互換性を維持したままである限りは、API仕様に則って開発されたアプリケーション側の変更は必要ない。アプリケーションがシステム／サービスを操作するにあたり、APIにだけ依存することでこのような互換性の問題を避けることができる。

隠しAPI

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

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

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

APIとプロトコル

APIはプロトコルの実装となっていることもある。
プロトコルは、共通の転送手段に基づいた要求と応答の標準的交換方法を定義している。一方プロトコルを実装していないAPIは、ライブラリとして実装され、直接使われるのが一般的である。したがってAPIには「転送手段」が関与することはなく（遠隔のマシンとの物理的情報転送を行わない）、「関数呼び出し」によって単純に情報交換し、データは特定の言語で表現された形式で交換される。
APIがプロトコルの実装である場合、下層にある通信プロトコルを使ってリモート呼び出しを行うためのプロキシ的手段となっている。その場合のAPIの役目は、プロトコルの詳細を隠蔽することである。例えばJava RMIは、JRMPプロトコルまたはRMI-IIOPとしてのIIOPを実装している。
プロトコルは一般に異なるテクノロジー（特定OS内の特定プログラミング言語に基づくシステム）間をつなぎ、それらの間での情報交換を可能にしている。一方APIは特定のテクノロジーに固有であり、何らかの変換手段を用いない限り、ある言語用のAPIを別の言語では使用できない。

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

オブジェクトAPIは具体的なオブジェクト交換フォーマットを規定し、オブジェクト交換プロトコルはメッセージ内の同種の情報をリモートシステムに転送する方法を定義する。
2つの異なるプラットフォーム間で、両者にあるオブジェクトを使ってプロトコル経由でメッセージを交換する場合、あるプログラミング言語内のオブジェクトは相手の異なる言語でのオブジェクトに変換される。例えばJavaで書かれたプログラムがC#で書かれたサービスをSOAPやIIOP経由で呼び出す場合、どちらのプログラムもリモート呼び出し用API（API自体はローカルに存在する）を使って情報交換し、ローカルなメモリ内でオブジェクトの変換を行う。
一方、同一マシン上でAPI経由のオブジェクト交換を行う場合、メモリ内で効率的に（オブジェクトまたはオブジェクトへの参照の）交換が行われる。例えば、1つのプロセスに割り当てられたメモリということもあるし、共有メモリを使って複数プロセス間で行うこともあるし、タプルスペースのような共有技法を使うこともある。

ウェブAPI

ウェブ開発においては、APIは一般にHTTP要求メッセージ群とXMLまたはJSON形式などの応答メッセージの構造定義で構成される。「ウェブAPI」はWebサービスと事実上同義だが、Web 2.0と呼ばれる最近の傾向では、SOAPベースからREST風の直接的通信へと変化している。ウェブAPIはマッシュアップと呼ばれる技法で複数のサービスを組み合わせて新たなアプリケーションとすることを可能にする。

実装

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を超えるバージョンで追加された機能を使用する場合は、android.os.Build.VERSIONクラスのSDK_INTフィールドの値に基づいて動的分岐する処理を実装する必要がある。

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

互換性のためのAPIを作成するためにそのAPIの実装を解析することは一般的に合法である。この手法は相互運用性のためのリバースエンジニアリングと呼ばれる。しかしAPIそのものとは異なり、APIの実装には著作権が存在するため、リバースエンジニアリングする前には著作権侵害の問題が生じないよう、十分注意する必要がある。また、使おうとしているAPIに、特許保持者の許可がなければ使えない特許技術が許可なく含まれていたら、それは特許権侵害になりうる。（ただし、これはリバースエンジニアリングに限られた話ではなく、APIを利用するプログラムにも全般的に言えることである。）
2010年、米オラクルはGoogleがJavaの新たな実装をAndroidの一部として配布したとして、Googleを訴えた。Java APIを複製する許可（ライセンス）はOpenJDKプロジェクトやIBM J9などの実装には与えられていたが、一方AndroidのDalvik仮想マシンの実装はOpenJDKなどに基づいてはおらず、またGoogleはJava APIを複製する許可をとっていなかった。これに対して、地方裁判所はAPIは著作権法の対象外であるとする判断を下したものの、控訴裁では保護対象であるとされ、最終的に2015年、最高裁によりアメリカ合衆国内ではAPIにも著作権があるとの判断が確定した。ただし著作権があってもフェアユースの下に利用可能かについては、2015年現在継続して審理されている。
日本においては、著作権法第10条第3項において、プログラムのインタフェースやプロトコルが著作物とみなされないことが明確に示されている。