<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[1]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> による <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor>) の悪い設計例やどう設計するべきかの指針のご紹介です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="138" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[138]</anchor-end> 何が良いかは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">諸説</anchor>あり<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">宗教的</anchor>で難しいですが、
悪いものには悪い理由があるので賛否はともかく参考になるはずです。</p><section><h1>バージョニング (版付け)</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[2]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> にバージョンを設けるべきではありません。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> の拡張は、常に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">後方互換性</anchor>を保った形で行うべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="3" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[3]</anchor-end> 従って <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPヘッダー</anchor>などにバージョン番号を指定させる必要はありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[7]</anchor-end> やむを得ず非互換変更せざるを得なくなった時は、非互換な機能のみ、
新しい<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エンドポイント</anchor>を設けるべきです。はじめから非互換変更するつもりで準備しておくのは無駄ですし、
非互換変更するための言い訳を用意するようなもので、危険です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="38" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[38]</anchor-end> バージョンが複数あるということは、同じものを複数メンテナンスし続けなければならないということです。バグやセキュリティーホールのリスクも増えます。場合によっては、混用された時におかしなことにならないかも注意しなければなりません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[39]</anchor-end> 実際それはつらいので、いつか古いバージョンへの対応をやめようとします。しかし、古いバージョンで問題なく使えていたクライアントは、無駄な変更コストが発生しますし、それによって新たにバグが生じることもあります。面倒に思ったり、コスト上の理由などで、それを機に対応を取りやめるクライアントもあるかもしれません。旧バージョンのアクセスが減ったと思って廃止したら、アクセス頻度が低いクライアントが利用できなくなって困る、というのもありそうです。 
バージョンを分ければ変更しやすくなるというのはその場しのぎでしかなく、
問題は先送りされているだけです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="88" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[88]</anchor-end> 結局、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> 提供者にとっても、クライアント開発者にとっても、クライアント利用者にとっても、嬉しいことは何一つありません。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="40" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[40]</anchor-end> シェアを背景に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> の非互換変更を頻繁に行う <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Facebook</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Twitter</anchor> は、雇用創出のための公共事業で仕様変更をやってるのではないかと揶揄されていますよ。
サーバー側がクライアント側より著しく高い政治力を持つ時だけうまく(?)いくモデルで、
参考にするべきではありません。</comment-p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="121" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[121]</anchor-end> あるサービスでは、バージョン番号として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">日付</anchor>を指定させています。
そのドキュメントには「現在の日付を指定するな」とわざわざ注記があります。</p><p xmlns="http://www.w3.org/1999/xhtml">クライアント開発者にとっては自分の書いたコードが1日でも長く無メンテナンスで使い続けられるのが良いですから、
現在の日付を指定したくなるのもわかります。そのような注記が必要だということ自体、
この方式が失敗していることを象徴しています。</p></example><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[122]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">バージョニング</anchor>は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web</anchor> の他の分野でも<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アンチパターン</anchor>として知られています。</comment-p></section><section><h1>特殊な要求メソッド</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[4]</anchor-end> 実用上、 <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code> と <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">POST</anchor></code>
(と <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OPTIONS</anchor></code> と <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HEAD</anchor></code>)
以外の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求メソッド</anchor>を使うべきではありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="6" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[6]</anchor-end> 意味的にもすべての操作をこの2つで十分明確に表現できます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="79" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[79]</anchor-end> <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PUT</anchor></code> や <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">DELETE</anchor></code> を使うべきだというのは宗教的な主張なので、
普通は <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">POST</anchor></code> で問題ありません。
最近は <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PATCH</anchor></code> 教も人気ですが、
流行に乗ればいいというものでもないでしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="5" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[5]</anchor-end> 特殊な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求メソッド</anchor>に対応していない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>のための代替手段として
<code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">X-HTTP-Method-Override:</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ヘッダー</anchor>に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求メソッド</anchor>を指定できるようにすることがありますが、
本末転倒です。正しい<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求メソッド</anchor>を使うべきです。</p><hr></hr><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="32" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[32]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">安全</anchor>で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">冪等</anchor>な操作にしか <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code> を使う(使える)べきではありません。
かつては <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> のためやむを得ず <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code> を使うことがありましたが、
今やただの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">セキュリティーホール</anchor>です。</p></section><section><h1>特殊な認証方式</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="8" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[8]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">認証</anchor>には <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本認証</anchor>か <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OAuth 2.0</anchor> <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bearer</anchor></code>
を使うべきです。いわゆる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">APIキー</anchor>認証は <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bearer</anchor></code>
で表現できます。 (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OAuth 2.0</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">認可フロー</anchor>を実装しなくても、
<code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bearer</anchor></code> だけ使えます。)</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="31" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[31]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">キャッシュ</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>アプリケーションを構成する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロキシ</anchor>、
または<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>が使っている<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロキシ</anchor>のもの。) による問題を防ぐためには、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP認証</anchor>の仕組みに乗るべきです。その意味で <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">query</anchor> や独自
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPヘッダー</anchor>に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">APIキー</anchor>を指定する方法は、安全ではありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="129" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[129]</anchor-end> <code>Bearer</code> と実質的に同じものなのに、独自の <code>auth-scheme</code>
名としている <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> もありますが、何のメリットもありません。避けるべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="80" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[80]</anchor-end> 独自の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">署名</anchor>を求める方式も、避けるべきです。歴史的には意味があったかもしれませんが、
今や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPS</anchor> が基本ですから、本当に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">署名</anchor>が必要な状況は稀です。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">署名</anchor>はデバッグが難しく、開発者を悩ませてきました。</p></section><section><h1>パスの濫用</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="21" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[21]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path</anchor> の濫用は慎むべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[22]</anchor-end> 例えば検索キーワードなどは <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL query</anchor> で指定するべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="23" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[23]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path</anchor> に任意の文字列が指定可能な場合、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>側の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パーセント符号化</anchor>漏れ、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> サーバー側の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">逆プロキシ</anchor>や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">WAF</anchor> の設定ミスによる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パーセント符号化</anchor>まわりの不具合などが起こりがちです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="35" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[35]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path</anchor> に任意の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> を埋め込めるのは、特に避けるべきです。</p></section><section><h1>動詞のパスを頑なに拒む</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="34" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[34]</anchor-end> よく <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path</anchor> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">名詞</anchor>がよく、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">動詞</anchor>は好ましくないと言われます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="48" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[48]</anchor-end> ただし整理上の都合で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">動詞</anchor>を使った方が綺麗になるなら、無理に避けるものでもありません。
たとえば <code>https://host/document/124345</code> の編集に関する操作は
<code>https://host/document/124345/edit</code> への <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">POST</anchor></code> に、
削除に関する操作は
<code>https://host/document/124345/delete</code> への <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">POST</anchor></code>
に実装しても何ら問題ないでしょう。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><code xmlns="http://www.w3.org/1999/xhtml">https://host/document/124345/edit</code> の <code xmlns="http://www.w3.org/1999/xhtml" class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code> が編集ページ、
<code xmlns="http://www.w3.org/1999/xhtml">https://host/document/124345/delete</code> の <code xmlns="http://www.w3.org/1999/xhtml" class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code>
が削除確認ページになっていると、ちょうど良い。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="65" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[65]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">動詞</anchor>を避けることで直感的でなくなったり、複雑になったりするのでは本末転倒です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="73" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[73]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="72" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;72</anchor-internal> も参照。</p></section><section><h1>何でもパスに入れたがる</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="66" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[66]</anchor-end> オプションを<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL query</anchor> や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求本体</anchor>の 
<code class="MIME" xml:lang="en">application/x-www-form-urlencoded</code>)
ではなく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パス</anchor>の一部に入れたがる人もいるようです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="67" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[67]</anchor-end> あまりどちらを使うべきか一概に言えるものでもないのですが、
次のような判断基準はたてられそうです。<figure class="list"><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="68" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[68]</anchor-end> 省略可能なオプションなら、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>で指定させた方が良い。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="69" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[69]</anchor-end> 値が長くなりそうなオプションなら、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>で指定させた方が良い。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="70" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[70]</anchor-end> 操作対象を指定する性質が強そうなオプションなら、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パス</anchor>に入れて良い。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="71" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[71]</anchor-end> いくつかのオプションがあって自明な順序がない 
(包含関係やユーザー○○の投稿××のような親子関係がない) なら、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>で指定させた方が良い。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="72" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[72]</anchor-end> 動作の指示は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>で指定させた方が良い。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="74" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[74]</anchor-end> 記号を値に含むなら (特に、普段は含まないがたまに含む場合)、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>で指定させた方が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パーセント符号化</anchor>を忘れるミスは防ぎやすい。</li></ul></figure></p></section><section><h1>用語が一貫していない</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="81" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[81]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> に登場する語 (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path</anchor> の一部分、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の名前、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">列挙型</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の値、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">オブジェクト</anchor>に含まれる名前など)
は、一貫した命名規則に従うべきです。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="82" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[82]</anchor-end> 例えば、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>のことを表すのに、 <code>user</code>、<code>usr</code>、<code>u</code>、
<code>account</code> のような似て非なる語・綴りを混在させるべきではありません。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="83" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[83]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">省略形</anchor>よりも<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">完全形</anchor>の方がわかりやすくて良いとする人もいます。
しかしやたらと長い方がかえってわかりにくくなったり、面倒くさかったりもします。
省略するべきかどうかは適宜判断すればよく、語の長さよりも一貫性の方が重要でしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="93" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[93]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">英単語</anchor>を連ねる場合、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">camelCase</anchor>、 <code>-</code>、<code>_</code>、<code>.</code>、
区切りなしなどいくつかの流儀があります。<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>の変数名などと同じく、
色々な人が色々な好みを持っていて、どれが優れているというものでもありません。
これもまた、一貫性を持たせることさえ心掛ければ、どの方法でも良さそうです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="98" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[98]</anchor-end> たぶん、これは <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> に限らず、開発プロジェクト全体で用語集を使って統一した方がよいでしょう。</comment-p></section><section><h1>変な状態符号</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>は適切に選択するべきです。エラーなら <code class="HTTP"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">4xx</anchor></code>
とするべきです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">決め方に迷ったら <code xmlns="http://www.w3.org/1999/xhtml" class="HTTP"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">4xx</anchor></code> 参照。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="47" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[47]</anchor-end> エラーだろうがなんだろうが構わず <code class="HTTP"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">200</anchor></code> を返すものは最悪です。
本文 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> データでエラーを表している場合でも、適切な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>を使うべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="128" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[128]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライブラリー</anchor>によっては<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>で正常かエラーかを判断したり、
開発者に有用なデバッグ用メッセージを生成したりといった機能があります。
これは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>がおおよそどのような性質のものであるかを<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>という
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> 全体で共通の方法で伝達できることの恩恵です。
たとえ詳細なエラーを別の方法で伝える必要があるとしても、
それはそれとして、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>は正しく設定するべきです。</p></section><section><h1>変なプロトコル</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[94]</anchor-end> 一昔前、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">XML-RPC</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SOAP</anchor> が若干流行ったことがありました。
しかし今では誰も使っていません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="95" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[95]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">WebDAV</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Atom API</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">AtomPub</anchor> が使われたこともありました。
今でも皆無ではありませんが、新規開発なら気にする必要はありません。
既存サービスとの互換性のようなことも、考えるだけ時間の無駄でしょう。</p><section><h1>意味のない互換性</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="96" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[96]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> のやり取りを共通化する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロトコル</anchor>はこの他にも色々と提案されてきましたが、
どれも大きな成功を収められていません。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webアプリケーション</anchor>はそれぞれに異なる要件と利用形態を持っていて、
どれだけ共通化しても、どうしても収まりきらない部分が出てきてしまいます。
するとサービスごとに独自対応せざるを得なくなりますが、
それならば初めからそれぞれの特性や利用方法に応じた独自の
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> とした方が、提供側も利用側も楽だったりするのでしょう。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> を使う、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> を使うといった基盤といえる部分を除けば、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロトコル</anchor>は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">標準化</anchor>には馴染まなそうです。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="97" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[97]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Twitter</anchor> と <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Facebook</anchor> は、扱うデータの形態や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>のアクションだけみれば
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> を共通仕様に揃えられそうなものですが、
両者の実際の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エンドポイント</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">データ構造</anchor>は全く異なります。
設計思想や歴史的な経緯の違いももちろんあるのでしょうが、
同じように見えても実際には全然異なる機能だったり、
違った形で利用されていたりして、簡単に共通化できるものでもなさそうですし、
それが各サービスの差別化要素にもなっているのでしょう。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="41" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[41]</anchor-end> 競合他サービスの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> に似せた <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> を提供しようとして、失敗している例をたまに見かけます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="42" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[42]</anchor-end> 完全互換ならクライアント開発者のメリットも多いでしょうが、実際には細かな差異がたくさんあったり、他サービスの仕様変更に追随できなかったりして、似て非なるものになっているのが普通です。すると他サービス用のコードを思ったほど流用できなかったり、境界ケースで正しく扱えず不具合が生じたりしがちです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="44" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[44]</anchor-end> 困るのは互換性があると信じて有名競合サービスとそれに似せた弱小サービスに対応した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>の開発者です。
有名競合サービスが仕様を変更し、弱小サービスが追随できない場合、
細かな分岐を増やすなり、コードを丸々コピーするなりしてがんばって両方への対応を維持し続けるか、
弱小サービスのサポートを終了するか、
弱小サービスのことを忘れていて仕様変更対応後に不具合が出てから気がつくか。
それならはじめから別のサービスは別のコードで実装していた方が良かったのではないでしょうか。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="43" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[43]</anchor-end> クライアント開発者の視点からすると、 (対象となるサービス自体のデータモデルが似ていることが前提で) 同じ操作が似たような手順で実行さえできればよく、そのエンドポイント名や引数名、応答のデータ構造などは (完全に一致しないなら) 合わせなくても良いように思えます。</p></section><section><h1>HTTPS を使っていない</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="29" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[29]</anchor-end> 常に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPS</anchor> を使う<SHOULD xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">べき</SHOULD>です。<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">平文のHTTP<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">素のHTTP</title></anchor> 
が好ましい理由は何もありません。
歴史的な理由で未だに <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> で <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> を提供するサービスも少なくありませんが、
それに倣うべきではありません。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="30" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[30]</anchor-end> 両方を提供する理由もありません。ただの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">セキュリティーホール</anchor>です。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="99" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[99]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">iOSアプリ</anchor>から利用する場合、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ATS</anchor> により標準で <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPS</anchor>
のみ有効になっています。アプリに設定を変更させるのは危険であり、避けるべきです。</p></section></section><section><h1>変な出力データ形式</h1><section><h1>変なデータ形式</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="9" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[9]</anchor-end> 出力データ形式は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> を基本とするべきです。
ほとんどの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フレームワーク</anchor>で、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> は標準で実装されています。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="33" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[33]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">XML</anchor> は追加ライブラリーが必要で面倒なクライアント環境やデータの扱いが面倒なライブラリー
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> が多いので、極力避けるべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="50" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[50]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CBOR</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MessagePack</anchor> のような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">バイナリー</anchor>ベースの形式を好む人もいます。
確かにサイズは抑えられ、 (実装次第ですが) <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> より高速に処理できるかもしれませんが、
ほとんどの場合は微々たる差で、より広く普及していてデバッグも容易な <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor>
の方が適切です。少なくても不特定多数の開発者に公開された <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor>
では、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> を基本とするべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[12]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は使うべきではありません。ただの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">セキュリティーホール</anchor>です。
異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">起源</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> からのアクセスが必要なら、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CORS</anchor>
を使うべきです。</p></section><section><h1>内容折衝</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> データ形式を選択制にするときは、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL query</anchor> または<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張子</anchor>で指定できるようにするべきです。
<code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Accept:</anchor></code> による選択は使うべきではありません。
杜撰な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">キャッシュ</anchor>の実装は <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Accept:</anchor></code> を正しく扱えません。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> で指定できる方が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">デバッグ</anchor>が容易です。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アクセスログ</anchor>に普通 <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Accept:</anchor></code>
は記録されないので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> に含めた方が便利です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="49" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[49]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>向けと <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> で同じ <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor>
を使い <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Accept:</anchor></code> によって<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">内容折衝</anchor>するような実装方法もありますが、
混乱を招くだけで誰も得しないので、避けるべきです。</p></section><section><h1>エラー応答の形式</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="36" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[36]</anchor-end> クライアントが機械的に処理することを想定したエラー応答は、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> など (成功時と同じ) 機械可読な形式で提供するべきです。例えば投稿エンドポイントは、
投稿エラーなら、投稿エラーを説明した <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> 応答を返すべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="37" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[37]</anchor-end> しかしだからといって、無理にどんなエラーでも <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor>
で返すようがんばる必要はないでしょう。例えばアプリケーションサーバーが過負荷で応答できないときの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">リバースプロキシ</anchor>のエラーまで敢えて
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> にしなくても構いません (しても構いませんが)。どうせクライアントは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態符号</anchor>以上の有益な情報をその応答から得られません。
クライアントはどのみち <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> でない時のエラー処理を実装しておく必要がありますから、
実装の手間も変わりません。</p></section></section><section><h1>変な MIME 型</h1><section><h1>独自の MIME 型</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="123" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[123]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>は <code class="MIME" xml:lang="en">application/json</code> です。
ほとんどすべての場合、これをそのまま使って何の問題もありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="124" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[124]</anchor-end> たまに、 <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">application/</anchor><var>service-name</var><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">+json</anchor></code>
のような独自の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>を使っていることがあります。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>は独自なのに、
データは普通の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> だったりします。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>の仕組みとして間違ったことではありませんが、
何のメリットもない、意味のないことです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="125" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[125]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライブラリー</anchor>によっては、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>が <code xmlns="http://www.w3.org/1999/xhtml" class="MIME" xml:lang="en">application/json</code>
の時 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> を扱いやすい機能を提供しているのに、独自の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>が使われるため、
その便利機能が使えないという可能性もあります。</comment-p></section><section><h1>MIME 型引数</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[78]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor> (<code>application/example; foo=bar</code> の <code>foo=bar</code>
のような部分) を使いたがる人がいるようです。一見便利に使えそうな場所ですし、
実際意味的に適切な場合もあるのですが、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MIME型</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の取扱いは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">相互運用性</anchor>に欠けるので、
あまりおすすめできません。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">実装によって、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の存在に対応していない、大文字と小文字の扱いが不適切、
複数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の指定順序の違いが不適切、
同名の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>が複数あるときの扱いがわからない、
値の特殊文字や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">非ASCII文字</anchor>の符号化の方法が混乱している、
といった色々な問題があります。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="142" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[142]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">versioning</anchor> に濫用した事案:
<code>application/vnd.elasticsearch+json</code></p></section></section><section><h1>JSON データ構造</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="45" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[45]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の場合、最上位は (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">配列</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プリミティブ値</anchor>ではなく)
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">オブジェクト</anchor>とした方が無難です。何かのリストを返したい時も、
後から他の付加データを増やしたいときに<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">配列</anchor>だとどうしようもないので、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">オブジェクト</anchor>でくるんでおくと良いでしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="46" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[46]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">識別子</anchor>などで桁数の多い<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>列を扱う時は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor>
の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数値</anchor>ではなく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>で表すように注意するべきです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> では構文解析時に32ビット整数に丸められてしまいます。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="118" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[118]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の <code>null</code>、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ブール型</anchor>、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数値</anchor>、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>の違いは、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>によっては区別されないことや違いが曖昧なことがあります。
従って、これらの違いを厳密に扱うことを要求するべきではありません。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="119" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[119]</anchor-end> 例えば、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>から <code>{&quot;foo&quot;: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">true</anchor>}</code> または
<code>{&quot;foo&quot;: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">false</anchor>}</code> のような値を受け取りたい場合、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の <code>ToBoolean</code> の挙動に寄せて、</p><ul xmlns="http://www.w3.org/1999/xhtml"><li>次のいずれかの場合は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偽</anchor><ul><li><code>foo</code> が指定されていない</li><li><code>foo</code> が <code>false</code></li><li><code>foo</code> が <n xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0</n></li><li><code>foo</code> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">空文字列</anchor></li></ul></li><li>それ以外の場合は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">真</anchor></li></ul><p xmlns="http://www.w3.org/1999/xhtml">... のようにすると、いろいろな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライブラリー</anchor>から無理なく扱えて好ましいと思われます。
(更に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Perl</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">bool context</anchor> の挙動に寄せて、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor> <code>0</code>
も<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偽</anchor>とみなすのもありかもしれません。)</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="51" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[51]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HAL</anchor> のような <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> ベースの言語を採用したり、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON Schema</anchor> のような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">スキーマ</anchor>に従って定義したりすることを好む人もいます。
そうしたものが有用な場面もあれば、あまり意味のない場面もありますから、
個別の用途に合わせて何を採用するか決めるべきです。「すべて○○を使うべき」
といった主張は眉唾物です。</p></section><section><h1>変なタイムスタンプ</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[13]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">日時形式</anchor>は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Unix time</anchor> を基本とするべきです。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ISO 8601の日時形式</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPの日時形式</anchor>、その他独自の形式は、
構文解析や生成処理や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">時間帯</anchor>処理が面倒でミスを誘発しがちなので、避けるべきです。</p></section><section><h1>HTTP ヘッダーの濫用</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[24]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPヘッダー</anchor>の濫用は避けるべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="25" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[25]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ページング</anchor>の指定は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL query</anchor> で行うのが伝統的な方法です。
それで何も問題ありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="26" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[26]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>による前後のページのリンクなどは、本文 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> データに含めるべきです。
<code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Link:</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ヘッダー</anchor>による指定は構文解析や生成処理が面倒でミスを誘発しがちなので、避けるべきです。
本文に含められない時は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> だけを値とする独自の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPヘッダー</anchor>を使うのが次善策です。</p></section><section><h1>変なページング</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="76" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[76]</anchor-end> 「投稿一覧」や「コメント一覧」のような追加や削除が起こり得る対象の一覧を時刻順で取得する
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> では、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ページング</anchor>にページ番号や先頭からの位置を取得するべきではありません。
最初のページと次のページの取得時点で位置が変化している可能性があるので、
項目の重複や欠落が発生する可能性があるからです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="77" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[77]</anchor-end> 「時刻 <var>t</var> より前、後」のような指定形式が良さそうですが、
同時刻に複数の項目が存在するかもしれないケースでは、
取り扱いが難しくなるかもしれません。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">マイクロ秒</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ナノ秒</anchor>の精度の時刻を使えば、そのようなケースはほとんど排除できそうです。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">秒</anchor>の精度では、重複はかなりの頻度で発生します。</p></section><section><h1>人間向けサーバーと API サーバー</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="57" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[57]</anchor-end> 人間向けサーバーと <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> のサーバーをどのように共存させるかは、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アプリケーション</anchor>の実装手法や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サービス</anchor>の規模と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">負荷分散</anchor>の戦略によって、
いろいろな手法が考えられます。実際、いろいろな方法が用いられています。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="58" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[58]</anchor-end> 例えば:<figure class="list"><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="59" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[59]</anchor-end> <code>https://service/page</code> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTML</anchor>) と <code>https://service/page.json</code> (API)
のように<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張子</anchor>で区別する</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="60" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[60]</anchor-end> <code>https://service/api/page</code> のように <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> を特定の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ディレクトリー</anchor>に収容する</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="61" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[61]</anchor-end> <code>https://www.serivce.example/page</code> と <code>https://api.service.example/page</code>
のように<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ホスト</anchor>で区別する</li></ul></figure></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="62" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[62]</anchor-end> 最初は小規模のサービスが大きくなった場合でも、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> で区別できるなら、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">リバースプロキシ</anchor>で接続先<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アプリケーションサーバー</anchor>を切り替えられますから、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">負荷分散</anchor>戦略によって <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の設計を過剰に制約する必要はありません。</p></section><section><h1>困ったドキュメント</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="14" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[14]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">人間</anchor>による明確なドキュメントを提供するべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="15" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[15]</anchor-end> 機械的に生成されただけのものは、ドキュメントとは言えません。
むしろドキュメントを整備した気になるだけなので有害です。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="27" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[27]</anchor-end> 例えば <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON Schema</anchor> から機械的に生成した <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTML</anchor>
ファイル群は、ただの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON Schema</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書き下し文</anchor>であって、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>ではありません。
もしや有用な情報が含まれているのでは、と読者の期待を煽ってしまうだけなので、
むしろ有害です。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="16" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[16]</anchor-end> 入出力や処理内容など必要な情報を過不足なく記述するべきです。
エンドポイントごとに一言コメントを並べたようなものは、メモ書きであり、
ドキュメントではありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[17]</anchor-end> また例示は例示であり、ドキュメントの本編ではありません。
例示をいくつ並べても、エンドポイントの説明とはいえません。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="52" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[52]</anchor-end> 有名な <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webサービス</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> であっても、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の実例を示しただけでまともな説明を加えていない「ドキュメント」
しか無いことがあります。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="131" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[131]</anchor-end> 主要な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>での利用例を示すこと自体は構いませんが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> でどのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求</anchor>を送信すると、どのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>を受信することになるか、
という説明を怠ってはいけません。 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>がどのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>でどのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライブラリー</anchor>を用いていようと、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> という共通の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロトコル</anchor>で等しく <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> にアクセスできることが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> の特徴であり、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">可能性</anchor>です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="28" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[28]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> によってアクセスされる対象であるオブジェクトの説明をがんばっているのに、
肝心の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> の部分、つまり <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP</anchor> でどのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求</anchor>が必要で、
どのような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>が送られるのかの説明が雑なことがよくあります。
サービスのオブジェクトモデルの説明は、もちろん重要な情報ですが、
それだけでは <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> のドキュメントになりません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="63" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[63]</anchor-end> 一読して理解できないレイアウトは避けるべきです。 API ドキュメントは、
デザイナーやエンジニアの自己表現の場ではありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="102" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[102]</anchor-end> 表示上の固定部分 (<code>position: fixed</code> など) はできるだけ避けるべきです。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ノートPC</anchor>などの狭い<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">画面</anchor>や、広い<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">画面</anchor>でも開発中の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アプリケーション</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">窓</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エディター</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">窓</anchor>などと同時表示している場合など、
狭い表示領域しか与えられないことがあります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="132" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[132]</anchor-end> 同じ理由で、本文の左右に目次や例示などで広い幅を占有する領域を配置するのは避けるべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="100" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[100]</anchor-end> 無駄にページ分割された構成は、一見整理されて使いやすく思えますが、
どんな機能があるか全体像をよく理解していない API 利用者にとっては望む機能がどこにあるか探しにくかったりします。
少ないページにまとめられていた方が、どんな機能が提供されているのか眺めやすいです。
例えば<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エンドポイント</anchor>ごとに別ページに分かれていたりすると、
極めて使いづらいドキュメントになります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="101" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[101]</anchor-end> 同じような理由で、見出しをクリックすると詳細説明が展開されるような、
一々細かく操作しないと全体を読めないドキュメントも使いづらいです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="141" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[141]</anchor-end> 
一つの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web頁</anchor>に内容がまとまっていれば、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>の標準のページ内検索機能で求めるものを見つけることができて、
便利なのです。</p><hr></hr><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="103" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[103]</anchor-end> 本サイトへのリンクがどこかにあるべきです。
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>トップページへのリンクがあっても本サイトへのリンクがない (かわかりにくい)
ことは意外とよくあります。)</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="104" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[104]</anchor-end> 例えば採用サービス候補がいくつかあって比較しているときなどに、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> ドキュメントと本サイトの機能ガイド、価格表などを行き来したいことがままあります。</p></example><hr></hr><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="139" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[139]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web頁</anchor>内検索を呼び出そうと <key xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">Ctrl</key> + <key xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">F</key>
を押すと、キャンセルして独自の検索機能を表示するドキュメントがあります。
ほとんどすべての場合、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>標準の検索機能の方が優秀なので、邪魔なだけです。
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー事業者</anchor>で勤務するトップクラスの技術者が時間をかけて作ったものと、
どちらが便利か、少し考えればわかりますよね。)</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="140" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[140]</anchor-end> ドキュメント (複数の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web頁</anchor>) の横断検索は、あれば便利なので、
別にフォームを用意して貰えればそれで良い。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>の標準機能を潰す必要はどこにもない。</p><section><h1>ドキュメント自体の URL</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="110" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[110]</anchor-end> 他の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">開発者</anchor>との情報交換や、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ソースコード</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コメント</anchor>などの形でドキュメントの一部を参照したいことがよくあります。
従って、</p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="111" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[111]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> をころころと変えるべきではありません。
新機能の追加などのタイミングでドキュメントを再編したくなるかもしれませんが、
元の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> で新しい場所に簡単にたどり着けるような配慮は絶対に必要です。
<weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(わかりやすいように再編すること自体は問題ありません。)</weak></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="113" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[113]</anchor-end> 1つの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文書</anchor>の内容が多岐にわたる場合は、
項目ごとに <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ID</anchor> を付与するべきです。
特に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エンドポイント</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">データ型</anchor>などは、
個別に参照したくなりそうなので、個々に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ID</anchor> を付与することが望ましいです。
できれば、章見出しをリンクとしたり、「§」マーク等でリンクしたりして、
読者が容易に気づけるようにするべきです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="112" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[112]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文書</anchor>の途中にリンクされた時の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">スクロール</anchor>効果など、
読者が求める情報に到達するまでに無駄な時間を浪費する機能を盛り込むべきではありません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="114" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[114]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フレーム</anchor>や、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">素片識別子</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">リンク</anchor>を使わない <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor>
による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">スクロール</anchor>・表示切り替えのような、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アドレスバー</anchor>の表示と実際の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文書</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> が異なってしまう技術を使うべきではありません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="115" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[115]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">スクロール</anchor>に追従して、あるいは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クリック</anchor>等の動作で、
勝手に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> (の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">素片識別子</anchor>) を書き換えるのは避けるべきです。
一見便利機能のようですが、読者が共有したいと思った <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> がいつの間にか違うものに書き換わっていたりして、案外不便です。</li></ul></section><section><h1>ドキュメントのプロトコル</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="107" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[107]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webサイト</anchor>で簡単に参照できるようにしておくべきです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ダウンロード</anchor>できるようにしても構いませんが、必須ではありません。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="108" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[108]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">素のHTTP</anchor>ではなく、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPS</anchor> で提供するべきです。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="109" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[109]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> 本体が <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTPS</anchor> なのに<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>だけ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">素のHTTP</anchor>
のサービスがありますが、なぜそうしようと思ったのか理解に苦しみます。
今となっては<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">素のHTTP</anchor>で提供するのが妥当である理由は何もなく、
サービス提供者の技術力の低さを露呈するだけです。</comment-p></section><section><h1>エンドポイント</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="130" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[130]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">path<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">URL path</title></anchor> 部分しか示していないドキュメントをたまにみかけますが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">scheme<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">URL scheme</title></anchor> や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ホスト</anchor>も含めてすべて示すか、
その説明に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">リンク</anchor>するべきです。なぜなら、
読者 (開発者) は望む機能を探してエンドポイントの説明ページを見て、
それをもとにコードを書くので、その時必要な情報がそこにすぐにあるべきだからです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="135" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[135]</anchor-end> 驚くべきことに、ドキュメントのどこにも書かれていないサービスすら存在します (!)。
API 提供者は一度でもその API を実際に使って何かを作ってみようとしたことがあるのでしょうか。
(自分達は API を使わずになんでもできてしまうので、意外となかったりします。
しかしそんな態度で果たして使いやすい API が提供できるかどうか。)</p></section><section><h1>値域</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="84" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[84]</anchor-end> 可能な値の範囲は、できるだけ明確に文書化するべきです。その際は、
将来の拡張も視野に入れ、限定しすぎず、かといって一般化もしすぎず、
適当な粒度とするべきです。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="85" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[85]</anchor-end> 例えば、あるサービスの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">識別子</anchor>を <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> でやり取りする場合、
おそらく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>もその識別子を何らかの形で保存しなければなりませんから、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ストレージ</anchor>上の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">データ型</anchor>を決めなければなりません。
識別子が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数値</anchor>なのか<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>なのか、含まれる文字の種類は何なのか、
最大の長さはどれだけなのか、といった情報が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>側開発者には有用です。</p><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="86" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[86]</anchor-end> ここで、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>側で識別子を32ビット整数型で表現しているとしても、
これをそのまま文書化することが望ましいとは限りません。将来の拡張の余地を残すため、
64ビットで表現可能な非負整数、と説明した方が良いかもしれません。</p><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="87" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[87]</anchor-end> 加えて、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>の識別子は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>によって互いに異なること、
決して他の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>に再割当てされることがないこと、
といった性質も、説明しておくのが良さそうです。
一方で、識別子は小さい順に連番で割り当てられる、という情報は書かないべきでしょう
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>側で有用な情報ではなさそうですし、将来サーバー側で割当方法を変更したくなるかもしれません)。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="116" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[116]</anchor-end> 「数値」や「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">タイムスタンプ</anchor>」や「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ISO 8601の日時形式</anchor>」のような曖昧な説明ではなく、
「1個<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ASCII数字</anchor>列によって表される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">十進整数</anchor>」、
「<cite>HTML Standard</cite> が規定する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">妥当な大域日時文字列</anchor>」
などの明確な説明とするべきです。</p><p>現実には残念ながらこれを怠る解説が少なくありません。
例えば「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ISO 8601の日時形式</anchor>」は無数の細かな選択肢がありますが、
それをすべて受け入れていることはほとんどありません。
技術ドキュメントは、異なる背景をもつ技術者同士が曖昧なく意思疎通できなければ意味がありません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="117" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[117]</anchor-end> 例示は、説明したことにはなりません。ドキュメントから例示をすべて取っ払ったときにも、
曖昧無く理解可能に記述するべきです。例示は理解の補助に過ぎません。</p></section><section><h1>ドキュメントのライセンス</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="133" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[133]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>の開発者が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>の一部を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コメント</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ソースコード</anchor>に書き込んだり、
提示されたサンプルコードを改変して利用したりすることは、よくあります。
これを安心して行わせるために、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>は自由度の高い<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライセンス</anchor>で提供するべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="134" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[134]</anchor-end> 具体的には、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CC0</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">MITライセンス</anchor>や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Apacheライセンス</anchor>が適切と思われます。</p></section><section><h1>コピペ可能性</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="136" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[136]</anchor-end> ドキュメント中の重要な部分は、一般的な <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>が簡単に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コピペ</anchor>できる状態になっているべきです。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="137" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[137]</anchor-end> ある <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webサービス</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ドキュメント</anchor>は、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エンドポイント</anchor>の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> をクリックすると詳細が開いたり閉じたりする形になっています。
<code>details</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要素</anchor>に相当するものですが、独自実装で、
テキストを選択しようとすると開いたり閉じたりして、選択は解除されてしまいます。
ドキュメントを読む人が、書かれている情報をどう利用するだろうか、
というところにもう少し想像力を働かせるべきでした。</p></example></section></section><section><h1>開発環境がない</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[18]</anchor-end> 提供されるサービスの性質次第ではありますが、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>の開発者が利用できる開発環境が提供されていると大変有用です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[20]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">課金</anchor>など重大な処理が伴うものや、通常のサービス利用では前提条件を構築するのが難しい処理などは、適当な開発環境が用意されているべきです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="19" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[19]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ホスト</anchor>を書き換える程度の手間で本番環境と切り替えられるのが理想的です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="53" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[53]</anchor-end> 有料サービスや審査制のものなどでは、開発者が容易にアクセスできる開発を提供することはとても重要です。
本格的な開発 (や契約その他) の前の評価段階の予備的開発のため、
特別な審査や費用などがなくても利用できるようにするべきです。</p></section><section><h1>API の設計ガイドライン</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="54" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[54]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ライブラリー</anchor>と同様に、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor>
にもこう設計するのが良い、悪いというような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">指針</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コーディング規約</anchor>のようなものが色々とあります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="55" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[55]</anchor-end> そうした指針類は、設計に迷った時のヒントとして有用かもしれませんが、
あまり意識しすぎても、無駄な制約でかえって開発しづらくなったり、
設計を歪めたりする危険性があります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[56]</anchor-end> 宗教性の高い指針には、特に自分の信仰と親和性が高そうに思った場合を除き、
従わない方が無難です。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="64" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[64]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">パス</anchor>などで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">単数形</anchor>にするか、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">複数形</anchor>にするか: 
どうでも良い。好きにすれば良い。その場その場で不自然でないようにすれば十分。</p></example><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="89" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[89]</anchor-end> 有名<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サービス</anchor>が採用している方針が、
常に好ましい方針とは限りません。真似る場合には、
自身の開発する対象にあわせて適切かどうかを都度検討するべきです。
長く続く有名サービスほど、歴史的な事情が積み重なっているはずです。
当該サービスの開発者自身も、おそらく何らかの不満を持っていることでしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="90" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[90]</anchor-end> 「宗教性」は、馴染みの薄い人には感じ取りにくいかもしれませんが、
次の各項に該当するなら要注意です。</p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="91" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[91]</anchor-end> やたらと 「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">REST</anchor>」 を強調している。 (00年代後半から10年代前半の流行語。)</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="92" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[92]</anchor-end> 「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URI</anchor>」が云々と言っている。 (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URI</anchor> は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> を意味する00年代の流行語。)</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[75]</anchor-end> 「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ベストプラクティス</anchor>」などと称する指針は、
その<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">著者</anchor>の思想が色濃くにじみ出た「ベスト」であると思って注意して読むべき。
いつでもどこでも誰でも「ベスト」な方針が存在するのなら、既にみんなそれに従っているはずで、
そうでないからこそ「ベスト」とわざわざ主張しているのである。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="105" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[105]</anchor-end> やたらと「すべて」、「必ず」のような強い要求をしている。 </li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[120]</anchor-end> 特定の手法を「美しい」などと謳っている。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="106" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[106]</anchor-end> この指針自体も、ある種の「宗教性」が感じられるかもしれません。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">信じるか信じないかはあなた次第</anchor>です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="126" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[126]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web</anchor> は、新技術開発が活発に行われ続けている、変化の速い分野です。
設計方針は、時代の変化への追随の足枷になるべきではありません。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="127" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[127]</anchor-end> 例えば、会社の意思決定の速度が遅い場合には、
会社の方針として設計の指針を定めるべきではありません。</p></example></section></body></html>