アプリケーションプログラミングインタフェース
テンプレート:WikipediaPage アプリケーションプログラミングインタフェース (API、英: Application Programming Interface) とは、ソフトウェアコンポーネントが互いにやりとりするのに使用するインタフェースの仕様である。APIには、サブルーチン、データ構造、オブジェクトクラス、変数などの仕様が含まれる。APIには様々な形態があり、POSIXのような国際規格、マイクロソフトの Windows API のようなベンダーによる文書、プログラミング言語のライブラリ(例えば、C++の Standard Template Library や テンプレート:仮リンク など)がある。
APIは Application Binary Interface (ABI) とは異なる。APIはソースコードベースだが、ABIはバイナリインタフェースである。例えば、POSIXはAPIだが、Linux Standard Base(LSB)はABIである[1](LSBはいろいろな規定の集合なので、正確には「LSBには、ABIにまで踏み込んでいる部分もある」)。
目次
概要
APIは、アプリケーションから利用できる、オペレーティングシステムやプログラミング言語で用意されたライブラリなどの機能の入り口となるものである。主に、ファイル制御、ウインドウ制御、画像処理、文字制御などのための関数として提供されることが多い。
つまり、簡単にいえば、アプリケーションをプログラムするにあたって、プログラムの手間を省くため、もっと簡潔にプログラムできるように設定されたインターフェースの事である。
APIを使うことでコンピュータソフトウェアが他のソフトウェアと広義の意味で通信しあうことができる。また低レベルな(機械寄りのプログラム言語を使う)ソフトウェアと高レベルな(人間寄りのプログラム言語を使う)ソフトウェアの間の関係をより抽象化するための方法である。APIの目的の一つは、ウィンドウやアイコンを描画するというような共通して使える機能(関数)を提供することである。そのような機能を使えば、プログラマーが一から百まで全部コーディングしなくても済むようになる。API自身は抽象的なものだが、APIを提供しているソフトウェアはそのAPIの実装と呼ばれる。
例えば画面に「Hello World」と表示させる仕事を考えると:
- 全部自分でやろうとすると
- 画用紙に「Hello World」という文字を書く。
- それを白と黒の四角いマスで表現したデータを作る。
- CPUがそのデータをディスプレイアダプターのフレームバッファに格納するプログラムを作成する。
- グラフィックカードを設定して、フレームバッファから正しく信号が生成されるようにする。
- オペレーティングシステム(OS)を使うと
- OSの機能を使うアプリケーションを使うと
- 「Hello World」と書いたHTMLドキュメントを作成し、Mozilla FirefoxやInternet Explorerなどのウェブブラウザに表示させる。
明らかに最初のやり方は手間がかかり、加えて相当な量の情報を渡さなくてはならないため実用的ではない。下に行くほどより簡単になっており、3つ目のやり方になると、「Hello World」とタイプすればいいぐらいの手間になる。
しかし高レベルなAPIには柔軟性がないことがある。例えばウェブブラウザで文字を点滅させながら円を描くように回転させることは難しいが、低レベルなAPIを使えばもっと簡単に実現できる。APIの簡潔さをとるか柔軟性をとるかは十分にトレードオフを考慮する必要がある。
APIの概念
APIは家の電気と同じようにコンピュータにとって非常に重要である。自分の家だろうが、友人の家だろうが、パンを焼きたい時にはトースターをコンセントにつなぐ。これはどちらの家でもコンセントという標準化されたインターフェースを備えているからである。もしコンセントがなければ、人は発電所までトースターを持参してパンを焼きにいかなくてはならなくなる。ヨーロッパのトースターは変圧器がなければ、アメリカでは動かないのと同じように、Windows用に書かれたプログラムは、WineなどのUNIXとの仲立ちをしてくれるAPIアダプターがなければUNIX上では動かないし、同様にUNIX用に書かれたプログラムはCygwinなどのソフトウェアを用いないとWindows上では動作しない。
APIにはさまざまな設計モデルがある。実行速度を考慮したインタフェースは通常、関数、プロシージャ、変数やデータ構造から構成される。また例えばECMAScriptの構文を解析するためのインタプリタであることもある。良いAPIはブラックボックスであり、良い抽象化層であると言える。すなわちプログラマはそのAPIの機能がより低レベルのAPIとどんな関係をもっているのかを知る必要がないのである。それはまた、そのAPIを使用しているコードを壊すことなく、APIの機能を再設計したり、改良したりすることを可能にしている。
使用料などを求められないAPIを「オープン」なAPIと言う。フリーソフトウェアで提供されるAPIはオープンなので、誰でもソフトウェアのソースを見たり、APIの実装を理解することができる。普通は、信頼ある組織からAPIの「リファレンス実装」が提供される(例えばWindowsのWindows API)。それに新たな機能を追加することもできる。例えば、Windows APIのほとんどはWineというソフトウェアとしてUNIXシステムに提供されている。
詳細
ひとつのAPIは特定の1つのタスクを実行する方法を記述している。C言語などの手続き型言語では、サブルーチン呼び出しによって実際の動作が行われる。したがって、APIは一般にそれが提供するあらゆる関数/ルーチンについて記述している。例えば math.h
というC言語用ヘッダファイルは数学的処理のためのC言語ライブラリ(通常 libm
と呼ばれる)で利用可能な数学関数の関数プロトタイプの定義を含んでいる。すなわちこのファイルは対応するライブラリに含まれる関数群の「使い方」を記述していると言える。関数プロトタイプは、関数名、関数の戻り値のデータ型、引数の個数とそれぞれのデータ型を示す。関数がどう動作するかは、より詳細に人間が読める形で記述され、本またはmanページのような電子形式で提供される。例えば、UNIXシステムのコマンド man 3 sqrt
は関数 sqrt
について次のような形式で説明を表示する。
SYNOPSIS
#include <math.h>
double sqrt(double X);
float sqrtf(float X);
DESCRIPTION
DESCRIPTION
sqrt computes the positive square root of the argument. ...
RETURNS
On success, the square root is returned. If X is real and positive...
これの意味するところは、その関数が正の浮動小数点数(単精度 (float) または倍精度 (double))の平方根を求め、それを浮動小数点数として返すものだということである。したがって、この場合のAPIは、C言語が使用するヘッダファイル群と人間が読める形のmanページでの説明で提供されていることになる。
APIドキュメンテーション
テンプレート:Main 多くのプログラム開発環境はAPIについての文書をデジタル形式で提供する仕組みを用意している。例えば、Perlには perldoc というツールがある。
$ perldoc -f sqrt
sqrt EXPRs
sqrt #Return the square root of EXPR. If EXPR is omitted, returns
#square root of $_. Only works on non-negative operands, unless
#you've loaded the standard Math::Complex module.
Python には テンプレート:仮リンク というツールがある。
$ pydoc math. sqrt
Help on built-in function sqrt in math:
math. sqrt = sqrt(...)
sqrt(x)
Return the square root of x.
Ruby には ri
というツールがある。
$ ri Math::sqrt
------------------------------------------------------------- Math::sqrt
Math.sqrt(numeric) => float
------------------------------------------------------------------------
Returns the non-negative square root of _numeric_.
JavaはHTML形式のページを生成する Javadoc がある。マイクロソフトでは、同社の各種言語(Visual C++、C#、Visual Basic、F#など)についてのAPI文書を Visual Studio のヘルプシステムに埋め込む形で提供している。
オブジェクト指向言語におけるAPI
オブジェクト指向言語では、APIには通常クラス群の定義が含まれ、それらクラスの動作についての説明が含まれる。この抽象概念は公開されている実際の機能と対応しており、クラス群のメソッド(あるいはより一般的には、公開されているメソッド群だが、フィールド、定数、入れ子オブジェクト、enumなども公開されていれば含まれる)によって実装されている。
この場合のAPIは、クラス群が公開する全メソッドの総体と理解することができる(これを一般にクラスインタフェースと呼ぶ)。すなわち、APIがメソッド群を規定し、それによってクラス定義から得られるオブジェクトとやりとりすることになる。
さらに一般化すれば、APIとはクラス定義から得られるあらゆるオブジェクトの集合体であり、それらのとりうる振る舞いの集合体である。結局公開されたメソッド群を通して使用するわけだが、APIの意味を考えたとき、メソッドはオブジェクトがどう振る舞うかの「技術的詳細」に過ぎない。
例えば、スタックを表現したクラス Stack
はスタックにアイテムを追加する push()
とスタックのトップからアイテムを取り出す pop()
という2つのメソッドを公開するだろう。
この場合のAPIは pop()
と push()
という2つのメソッドと解釈することもできるし、より一般的にはスタックの振る舞いを実装した Stack
という型のアイテムを使用できるという「考え方」でもある。後者の解釈の方がオブジェクト指向の精神にふさわしい。
この概念を推し進めると、API内のクラスインタフェースに全くメソッドが存在せず、単に振る舞いだけが定義されているという地点にまで到達する。例えば、Java や LISP のAPIには Serializable
というインタフェースがある。これはマーカーインタフェースであり、それぞれのクラスがどうシリアライズするかを実装しなければならない。これは公開されたメソッドを持つことを要求するわけではなく、むしろ任意の時点でセーブ(シリアライズ)できる表現を持つことを、そのインタフェースを実装する任意のクラスに要求する(外部リソースへのリンクを持たない単純なデータしか持たないクラスでは常に成り立つが、ファイルや遠隔システムや外部デバイスへのオープンコネクションを持つ場合はその限りではない)。
同様に、並行(マルチスレッド)環境におけるオブジェクトの振る舞いは、実装されたインタフェースに属する特定のメソッド群によっては必ずしも決定されないが、依然としてそのクラスのオブジェクトについてのAPIに属しており、文書によって説明されるべきである[2]。
そういった意味で、オブジェクト指向言語におけるAPIは、主にクラスメソッド群で実現されるオブジェクトの振る舞いのセットを定義したものと言える。
そのような言語でも、APIはライブラリの形で配布される。例えば、Javaのライブラリは開発者が新たなJavaプログラムを開発する際に使用するJDKという形で提供されるAPIのセットを含む。JDKにはJavadoc形式で生成されたAPIドキュメンテーションが含まれている。
APIに関する文書の品質はAPIの使いやすさを左右し、そのAPIの成功を決定付けることが多い。
ライブラリとフレームワーク
APIはソフトウェアライブラリと対応しているのが一般的である。APIは「期待される挙動」を規定し説明するが、ライブラリはその規則群の「実際の実装」である。1つのAPIが複数の実装を持つこともあるし、実装のない抽象的APIもありうる。
APIはソフトウェアフレームワークと対応する場合もある。フレームワークはいくつかのライブラリを備え、いくつかのAPIを実装することもあるが、通常のAPIとは使い方が異なり、「フレームワークに組み込まれた」挙動への「アクセス」としてフレームワーク自身に新たなクラスをプラグインすることでその内容を拡張するという手段をとる。さらに言えば、呼び出し側はプログラムの動作を制御できず、制御の反転や他の類似の機構によってフレームワーク側が流れを制御する[3]。
APIとプロトコル
APIはプロトコルの実装となっていることもある。
プロトコルは、共通の転送手段に基づいた要求と応答の標準的交換方法を定義している。一方プロトコルを実装していないAPIは、ライブラリとして実装され、直接使われるのが一般的である。したがってAPIには「転送手段」が関与することはなく(遠隔のマシンとの物理的情報転送を行わない)、「関数呼び出し」によって単純に情報交換し、データは特定の言語で表現された形式で交換される[4]。
APIがプロトコルの実装である場合、下層にある通信プロトコルを使ってリモート呼び出しを行うためのプロキシ的手段となっている。その場合のAPIの役目は、プロトコルの詳細を隠蔽することである。例えば Java RMI は、テンプレート:仮リンクプロトコルまたはRMI-IIOPとしてのIIOPを実装している。
プロトコルは一般に異なるテクノロジー(特定OS内の特定プログラミング言語に基づくシステム)間をつなぎ、それらの間での情報交換を可能にしている。一方APIは特定のテクノロジーに固有であり、何らかの変換手段を用いない限り、ある言語用のAPIを別の言語では使用できない。
オブジェクトAPIとプロトコル
オブジェクトAPIは具体的なオブジェクト交換フォーマットを規定し、オブジェクト交換プロトコルはメッセージ内の同種の情報をリモートシステムに転送する方法を定義する。
2つの異なるプラットフォーム間で、両者にあるオブジェクトを使ってプロトコル経由でメッセージを交換する場合、あるプログラミング言語内のオブジェクトは相手の異なる言語でのオブジェクトに変換される。例えばJavaで書かれたプログラムがC#で書かれたサービスをSOAPやIIOP経由で呼び出す場合、どちらのプログラムもリモート呼び出し用API(API自体はローカルに存在する)を使って情報交換し、ローカルなメモリ内でオブジェクトの変換を行う。
一方、同一マシン上でAPI経由のオブジェクト交換を行う場合、メモリ内で効率的に(オブジェクトまたはオブジェクトへの参照の)交換が行われる。例えば、1つのプロセスに割り当てられたメモリということもあるし、共有メモリを使って複数プロセス間で行うこともあるし、タプルスペースのような共有技法を使うこともある。
仮想機械を通したAPIの共有と再利用
1つの仮想機械で動作する複数の言語は、APIを共有できる。例えば、共通言語ランタイムで動作する言語群やJava仮想マシンで動作する言語群がある。
その場合、中間的なバイトコードと言語束縛を使って特定言語から抽象化するという仮想機械の特徴により、言語間の相互運用が可能となる。
これにより、既存のライブラリ群とそのAPIについて、コードの再利用の可能性が大きくなる。
ウェブAPI
テンプレート:Main ウェブ開発においては、APIは一般にHTTP要求メッセージ群とXMLまたはJSON形式などの応答メッセージの構造定義で構成される。「ウェブAPI」はWebサービスと事実上同義だが、Web 2.0 と呼ばれる最近の傾向では、SOAPベースからREST風の直接的通信へと変化している[5]。ウェブAPIはマッシュアップと呼ばれる技法で複数のサービスを組み合わせて新たなアプリケーションとすることを可能にする[6]。
ウェブによるコンテンツ共有
APIを公表する慣習により、ウェブコミュニティにはコミュニティ間やアプリケーション間でコンテンツとデータを共有するオープンアーキテクチャが発展していった。そのため、ある場所で作成されたコンテンツはウェブ上の様々な場所で盛んにポストされ更新される。
- 写真は Flickr や Photobucket といったサイトから Facebook や Myspace といったソーシャルネットワークサイトに共有される。
- コンテンツは埋め込むこともできる。例えば、SlideShare にあるプレゼン資料を LinkedInのプロファイル情報に埋め込むことができる。
- TwitterのつぶやきをFacebookの投稿にも同時に反映させるAPIもある。
- 動画コンテンツも別のホスト上のサイトに埋め込むことができる。
- ウェブコミュニティにおけるユーザー情報を外部アプリケーションと共有させることができ、アプリケーションの更新をウェブ側から働きかけるなどの機能もオープンなAPIで実現されている。好例としてテンプレート:仮リンクやOpenSocialプラットフォームがある。
実装
POSIX標準は、様々な一般的コンピューティング機能を各種システム上で実装できるよう考慮したAPIを定義している。例えば、OS X やBSD系システムで実装されている。ただし、POSIX準拠のプログラムを別のPOSIX準拠のプラットフォームで実行するには、再コンパイルが必要である。一方、互換APIの場合、そのAPIを実装したシステムならどこでも同じオブジェクトファイルがそのまま実行可能である。これはソフトウェア業者にもユーザーにも有益であり、業者は互換APIが実装されていれば新システムが登場しても製品を修正せずに済むし、ユーザーも古いソフトウェアを新システムにインストールできる。ただし、それには一般に各種ライブラリが必要なAPI群を実装している必要がある。
マイクロソフトはAPIの後方互換性の維持を心がけており、特に Windows API (Win32) ライブラリは古いアプリケーションが新しいWindows上でも動作できるよう互換モードを備えている[7]。
Unix系OSでは、相互に関連はあるが非互換なOS群が同一ハードウェア上で動作している。ソフトウェア業者が同一バイナリで各種OSに対応できるようAPIとABIを共通化する試みがなされてきたが、いずれも失敗に終わっている。そのような試みとしてLinuxでは Linux Standard Base がある。BSD系OSも各種あるが、互換性のレベルは様々である。
公開の方針
APIの公開に関しては2つの一般的な方針がある。
- 自社のAPIを厳重に秘匿する。
- 自社のAPIを広く普及させる。
この2つの方針の中間もある。
リバースエンジニアリングと著作権
互換性のためのAPIを作成するためにそのAPIの実装を解析することは一般的に合法である。この手法は相互運用性のためのリバースエンジニアリングと呼ばれる。しかしAPIそのものとは異なり、APIの実装には著作権が存在するため、リバースエンジニアリングする前には著作権侵害の問題が生じないよう、十分注意する必要がある。また、使おうとしているAPIに、特許保持者の許可がなければ使えない特許技術が許可なく含まれていたら、それは特許権侵害になりうる。(ただし、これはリバースエンジニアリングに限られた話ではなく、APIを利用するプログラムにも全般的に言えることである。)
2010年、オラクルはGoogleがJavaの新たな実装をAndroidの一部として配布したとして、Googleを訴えた[8]。Googleは Java API を複製する許可をとっていなかったが、類似の許可はOpenJDKプロジェクトに与えられていた。OpenJDKはGPLでライセンスされているので、自由に改変できる。この裁判で、アメリカ合衆国内ではAPIに著作権はないとの判断が下された[9][10]。
APIの例
- ASPI - SCSIデバイス用インタフェース
- CarbonとCocoa - OS X
- CORBA
- Document Object Model (DOM) - HTML文書やXML文書をアプリケーションから利用するためのAPI
- DirectX - Microsoft Windows
- EHLLAPI
- HTMLレンダリングエンジン(例えばWebKit)
- iconv - 文字コード間の相互変換用API(POSIXの一部)
- I/OKit - Darwin
- テンプレート:仮リンク
- ODBC - Microsoft Windows
- OpenAL - クロスプラットフォームのオーディオAPI
- OpenCL - CPUやGPUを汎用処理に使用するためのクロスプラットフォームのAPI
- OpenGL - クロスプラットフォームのグラフィックスAPI
- OpenMP - クロスプラットフォームの共有メモリ型マルチプロセッシング用API。C、C++、Fortran で利用可能。
- POSIX
- QuickTime
- Single UNIX Specification
- Simple DirectMedia Layer (SDL)
- Toolbox - Mac OS
- Video for Windows - Microsoft Windows
- Windows API - Microsoft Windows
- XPCOM
- パソコンのBIOSコールインタフェース
言語束縛とインタフェースジェネレータ
複数の高水準言語での使用を意図したAPIは、文法的・意味的に各言語に適したインタフェースをAPIに自動的にマッピングする機能を提供している。これを言語束縛と呼び、それ自体もAPIである。その目的は、そのAPIに要求される機能のほとんどをカプセル化するため、各言語に薄い層を設けることである。
以下に挙げたものは、コンパイル時に言語とAPIの束縛を行うインタフェースジェネレータである。
- SWIG - オープンソースの多言語間のインタフェースジェネレータ(通常はC/C++からスクリプト言語へのインタフェースを生成)
- F2PY:[11] - Fortran から Python へのインタフェースジェネレータ
脚注
関連項目
外部リンク
- What is an API? Your Guide to the Internet (R)evolution
- How to design a good API and why it matters
- How to Design APIs for Cryptographic Protocols