[18] [DFN[[[REST]]]] は、 [[Web]] の[[プロトコル]]や [[API]]
の設計に大きな影響を与えた[RUBYB[[[体系様式]]]@en[architectural style]]です。

* 意味

[19] 現在では[[バズワード]]となった「[[REST]]」の意味は発散しており、 「[[Web]]
を使った何か」程度の言葉と理解するべきかもしれません。

[30] [[REST]] に沿っていることを [DFN[[[RESTful]]]] といいます。

;; 具体的にどんな条件が満たされれば [[RESTful]] と言えるかは定かではありません。
色々な人が好き勝手なことを言っています。

;; [70] 似たような語で [DFN[RESTish]] というものがあります。
[[RESTful]] と同義だったり、違うと主張する人もいたり、
好き勝手で共通の意味が見えないのは同じです。
[[RESTful]] ほど知名度はありません。

* REST に従っていると主張されるものの例

[31] [[REST]] に従っていると設計者または利用者等が特に主張している[[プロトコル]]には、
次のものがあります。

[FIG(short list)[
- [[HTTP]]
- [[SOAP 1.2]]
- [[WSDL]]
- [[AtomPub]]
- [[LDP]]
- [[CoAP]]
- [[OData]]
- [[HATEOAS]]
- [[Web Annotation Protocol]]
]FIG]

[32] その他いろいろな [[Web API]] が [[RESTful]] であるなどと主張しています。

;; 「REST API」と言ったり「RESTful API」と言ったりしますが、
どちらも同じ意味です。 (そしてどちらも「Web API」と大して意味は違いません。)

[61] 沢山あってきりがないですが、中でも特に [[REST]] であることを強く主張しているもの:
[FIG(short list)[
- [[REST-OA]]
- [[RESTCONF]]
]FIG]

[41] [[REST]] にしようという話をよく聞いてみると、 [[HTTP]]
を正しく使おうというだけの話だった、ということもあります。

[63] [[REST]] 用とされるものの例:
[FIG(short list)[
- [[WADL]]
- [[RAML]]
- [[Swagger]]
- [[OpenAPI Specification]]
- [[Hydra]]
- [[CPHL]]
- [[Linked Data Templates]]
- [[restQL]]
- [[RestQL]]
]FIG]

* 「REST API」による HTTP の濫用例

[14] 近年の「REST」API の類は従来 [[URL]] に含めていたデータを [[HTTP]]
の機能で表すのが [[cool]] だと思っているようです。 そのような例は:

[FIG(list)[
- [17] 操作の種類を[[要求メソッド]] [CODE(HTTP)@en[[[PUT]]]]、
[CODE(HTTP)@en[[[DELETE]]]]、[CODE(HTTP)@en[[[PATCH]]]] として表す
- [16] [[ページ番号]]を[[範囲単位]] [CODE(HTTP)@en[[[items]]]] で表す
- [23] 出力のデータ形式を [CODE(HTTP)@en[[[Accept:]]]] [[ヘッダー]]で表す
- [15] [[API]] の版を [CODE(HTTP)@en[Accept:]] [[ヘッダー]]で表す
- [67] 出力のバリエーションを [CODE(HTTP)@en[Accept:]] [[ヘッダー]]で表す
- [24] 出力のバリエーションを [CODE(HTTP)@en[[[Prefer:]]]] [[ヘッダー]]で表す
- [33] [[API]] の[[版]]を独自の [[HTTPヘッダー]]で表す
- [28] [[要求]]に関するその他の[[引数]]を独自の[[HTTPヘッダー]]で表す
- [60] [[MIME型]]の[[引数]]を使いたがる
]FIG]

[20] こういうのって「なんでも [[URI]] で表せる」という [[Semantic Web]]
的世界観とは矛盾する気がしますが、 [[REST]] 系の人は気にしないのですかね。

[29] 実際不便だからか何なのか、[[ヘッダー]]等による指定だけでなく
[[URL query]] などの指定もできるようにしている [[API]] も少なからずあります。
実装コストや不具合リスクが上がるだけで何も得していない気がしますが・・・。

[25] 関連する [[JSON]] [[Web API]] の [[URL]] を [[JSON]] [[応答]]内に含める
[[HAL]] 的なものを好ましいと思っている人達 (その人達もそのやり方が [[REST]]
っぽくて [[cool]] だと思っていそう...) のやり方とも衝突するような気がしないでもない。。。

[43] [[URL]] 相当のものを [[URL]] 以外で表す他にも、
次のようなものが [[REST]] 的であると評されたり、
[[REST]] の条件であると主張されたり、
[[REST]] を名乗る [[API]] が使っていたりします。 (色々な派閥があるようで、
相互に矛盾したものもありますが...)

[FIG(list)[
- [45] [[URL]] に[[拡張子]]を含めない
- [44] [[API]] のバージョンを [[URL]] に含める
- [[Cool URI]]
- [43] 通常の [[JSON]] や [[XML]] の [[MIME型]]を使わずに、当該サーバー専用の
[[MIME型]]を使う
- [46] [[JSON]] を使う
- [47] [[Web Linking]] の[[リンク型]]を使う
- [48] [[JSON Schema]] の類を使う
- [49] 独自の [CODE(ABNF)@en[[[auth-scheme]]]] を作って使う
- [50] [CODE(HTTP)@en[[[Link:]]]] [[ヘッダー]]を使う
- [51] [[JSON]] [[応答]]に他の [[API]] の [[URL]] を含める
- [52] [CODE(HTTP)@en[[[PUT]]]] や [CODE(HTTP)@en[[[PATCH]]]] や
[CODE(HTTP)@en[[[DELETE]]]] を使い、 [CODE(HTTP)@en[[[POST]]]] は使わない
]FIG]

[66] [[URL]] に「[CODE[/api/]]」のような[[文字列]]を含めることも、
[[REST]] 信奉者的には余り問題が無いみたいです (もしかすると派閥もあるのかもしれませんが)。
[[Cool URI]] 教では好かれない設計のような気がします。
それとも[[拡張子]]ではないから特に問題ない、ということなのでしょうか。

[68] [[URL]] に API のバージョンを入れるというのも、 [[Cool URI]]
とは正反対の考え方ですよね。。。

[72] 具体例は[[悪いWeb API設計]]も参照。

* REST と対立すると言われるものの例

[38] 次のものは [[REST]] と対立する技術だったり、 [[REST]] でないと言われたりする要素です。

[FIG(list middle)[ [65] 色々な「[[REST]] 的でない」とされるもの
- [[RPC]]
- [[XML-RPC]]
- [[SOAP]]
- [[JSON-RPC]]
- [[URL]] に動作が含まれる
- [CODE(HTTP)@en[[[GET]]]] や [CODE(HTTP)@en[[[POST]]]] しか使わない
- [[HTTP]] [[状態符号]]をあまり活用しない
- [[ハイパーメディア]]を使わない
- [[WebSocket]]
- [[GraphQL]]
- [[YASMIN]]
- 複数の[[資源]]をまとめて操作
- [[URL]] に[[拡張子]]が含まれる
]FIG]

[35] [[RPC]] は [[REST]] でないというのが一般的な見解のようですが、
[[RPC]] を [[REST]] で作ったなどと主張するものもあったりするようです。

[36] [[REST-RPC]] が [[REST]] なのか [[RPC]] なのか両方なのかどちらでもないのかよくわかりません。
[[REST-RPC]] が [[REST]] であったり [[REST]] でなかったりすることもあるようです。

[37] [[SOAP]] は元々 [[REST]] とは対立するものだったのが、 [[W3C]] で [[SOAP 1.2]]
を開発した結果 [[REST]] になった、とされています。

;; [71] 「[[REST]] になった」結果良くなったかどうか不明です。
[[非互換変更]]が多く移行が進まず [[SOAP 1.1]] と [[SOAP 1.2]] の両方並立する状態になりました。
ぜひとも移行したいほどの魅力を [[SOAP 1.2]] が持ち合わせなかったのは事実でしょう。

* メモ

[1]
[CITE[傭兵日記: REST の日本語リソース]] <http://yohei-y.blogspot.com/2004/12/rest.html>
([[名無しさん]])

[2]
- [CITE[How I explained REST to my wife...]] <http://naeblis.cx/rtomayko/2004/12/12/rest-to-my-wife>
- [CITE[奥さんに REST をどう説明したかというと…]] <http://www.geocities.jp/yamamotoyohei/rest/rest-to-my-wife.htm>

妙に理解力のある奥さんだ[AA[w]]
([[名無しさん]])

[3]
[CITE[傭兵日記: REST 入門]] <http://yohei-y.blogspot.com/2005/04/rest_23.html>
([[名無しさん]])

[4]
[CITE[REST - 羊堂本舗 ちょき]] <http://sheepman.parfait.ne.jp/wiki/REST>
([[名無しさん]])

[5]
[CITE[Architectural Styles and the Design of Network-based Software Architectures]] <http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm>
([[名無しさん]])

[6]
[CITE[川o・-・)<2nd life - RESTWiki]] <http://d.hatena.ne.jp/secondlife/20050914/1126631161>
([[名無しさん]])

[7]
[CITE[はてなブックマーク - 第八回XML開発者の日]] <http://b.hatena.ne.jp/entry/http://www.asahi-net.or.jp/~eb2m-mrt/kaihatsu8.html>
([[名無しさん]] [WEAK[2005-11-26 01:55:52 +00:00]])

[8]
[CITE[REST でよくある間違い]] <http://www.geocities.jp/yamamotoyohei/rest/mistakes.html>
([[名無しさん]] [WEAK[2005-11-27 02:02:40 +00:00]])

[9]
[CITE[rest - Microformats]] <http://microformats.org/wiki/rest/>

([[名無しさん]] [WEAK[2005-11-29 10:24:42 +00:00]])

[10]
[CITE[RestWiki: Front Page]] <http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage>
([[名無しさん]] [WEAK[2006-07-16 08:42:33 +00:00]])

[26] 最初は [[XML-RPC]] や [[SOAP]] のようなものに対する [[REST]]
という対立構造だった気がしますが、いつの間にか [[SOAP 1.2]] は「REST に基づいている」
みたいなことになっていた。。。

[11]
[CITE[スラッシュドット ジャパン | ミクシィ、画像に認可制御なしの欠陥を改修できず、ヘルプで弁解]] <http://slashdot.jp/security/article.pl?sid=06/10/17/1958219&from=rss>
([[名無しさん]] [WEAK[2006-10-20 00:35:24 +00:00]])

[27] その後 [[SOAP]] などが話題にもならなくなって、 [[REST]]
という言葉も忘れ去られていくのかと思っていたら、
10年代になってまた (10年ぶりくらいに) 流行りだした...

[13] 最近は [[REST]] の意味もよくわからなくなってきましたね。みんな自分の好きなスタイルのことを
[[REST]] と呼んで自己正当化してるだけのような・・・。

[12] [CITE@en[RESTful API Design, Second Edition]]
( ([TIME[2013-02-08 03:24:31 +09:00]] 版))
<http://www.slideshare.net/apigee/restful-api-design-second-edition>

[21] [CITE[続・コマンド的な処理をどうやってRESTfulに実装するか - 岩本隆史の日記帳]]
( ([TIME[2012-04-12 08:38:46 +09:00]] 版))
<http://d.hatena.ne.jp/IwamotoTakashi/20090326/p1>

[22] [CITE[技術/HTTP/REST設計思想の "Stateless" との付き合い方 - Glamenv-Septzen.net]]
([TIME[2015-02-13 16:40:15 +09:00]] 版)
<http://www.glamenv-septzen.net/view/1350>

[FIG(amazon)[
[[REST]]
]FIG]

[34] [CITE[REST APIs must be hypertext-driven » Untangled]]
([TIME[2015-11-19 13:20:21 +09:00]] 版)
<http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven>

[39] [[REST API]] は [[URL]] が割り当てられた各オブジェクトを個別に取得したいときは単純で良いのですが、
複数まとめて取得したいとき、標準的な方法が用意されていないのが困りものです。
実装依存の方法で、複数のオブジェクトを query で指定したり、
複数の[[HTTP要求]]をひとまとめにしたりすることができる場合もあれば、
そのような方法が何も用意されていない場合もあります。

[40] [[持続的接続]]や [[HTTP/2]] を使えばいいと考える人もいるのでしょうが、
サーバー側もたぶん複数回のデータベースアクセスが発生するよりまとめて一度に取得できる方が負荷その他の点から嬉しいはずです。


[FIG(quote)[
[FIGCAPTION[
[42] [CITE[Is my API RESTful when I use JSON? | - The RESTful cookbook]]
([[]] 著, [TIME[2015-05-18 19:08:49 +09:00]] 版)
<http://restcookbook.com/Mediatypes/json/>
]FIGCAPTION]

> One of the key constrains on REST is that a RESTful API must use hypermedia formats (the HATEOAS constraint). 

]FIG]


[FIG(quote)[
[FIGCAPTION[
[53] [CITE[REST vs SOAP]]
([TIME[2010-11-12 16:40:00 +09:00]] 版)
<http://xmlconsortium.org/wg/web2.0/teigensho/4--REST-SOAP.html>
]FIGCAPTION]

> RESTの使用例の一つに「RSS配信」がある。RSS配信では、特定のURLにアクセスすると、XMLのRSSフォーマットで記述されたデータが配信される。

]FIG]


[FIG(quote)[
[FIGCAPTION[
[54] [CITE[REST vs SOAP]]
([TIME[2010-11-12 16:40:00 +09:00]] 版)
<http://xmlconsortium.org/wg/web2.0/teigensho/4--REST-SOAP.html>
]FIGCAPTION]

> 明確な仕様がないために「どこまでをRESTと呼ぶか」については様々な主張があるが、ここでは『HTTPのGETメソッドを使ってあるURLにアクセスすると、XMLが返ってくる』ものをRESTと呼ぶ。セッションやPOSTを使えば複雑な事も実現可能だが、今回はGETを使ったシンプルなRESTを想定している。

]FIG]


[FIG(quote)[
[FIGCAPTION[
[55] [CITE[RESTとは|REpresentational State Transfer - 意味/定義 : IT用語辞典]]
([TIME[2016-03-25 11:58:05 +09:00]] 版)
<http://e-words.jp/w/REST.html>
]FIGCAPTION]

> 一般によく使われる狭義のRESTは、パラメータを指定して特定のURLにHTTPでアクセスすると、XMLで記述されたメッセージが送られてくるようなシステムおよび呼び出しインターフェース(「RESTful API」と呼ばれる)のことを指す。システムの状態やセッションに依存せず、同じURLやパラメータの組み合わせからは常に同じ結果が返されることが期待される。ただし、厳密な技術的定義が共有されているわけではなく、「SOAPやRPCなどを必要としない、XMLベースの単純なWebインターフェース」くらいの意味で用いられる場合が多い。

]FIG]


[FIG(quote)[
[FIGCAPTION[
[56] [CITE[Sand Box #6810: Railsの擬似RESTにPut/Deleteを投げる2つの方法]]
([TIME[2014-10-07 14:30:41 +09:00]] 版)
<http://sandbox-6810.blogspot.jp/2011/11/railsrestputdelete.html>
]FIGCAPTION]

> PUT/DELETEをしたいときは、httpのメソッド的にはPOSTを使いながらも、
> これはPUTです、これはDELETEです、というフラグを合わせることで、
> RESTfulっぽいインターフェースを実現しています。
> これが擬似REST方式です。

]FIG]


[57] [CITE[調査:著名サイトのパスワードリセット用 URL - Qiita]]
( ([TIME[2016-06-17 13:29:12 +09:00]]))
<http://qiita.com/t-suwa/items/f3969be0fdf21112e8fe>

[FIG(quote)[
[FIGCAPTION[
[58] [CITE@en[Apple News API Reference: About the Apple News API]]
( ([TIME[2016-06-29 11:20:45 +09:00]] 版))
<https://developer.apple.com/library/ios/documentation/General/Conceptual/News_API_Ref/>
]FIGCAPTION]

>  The Apple News API has typical RESTful characteristics:
>     Has a set of resources; for example, channels and articles
>     Provides stateless create, read, update, delete (CRUD) operations on resources
>     Uses JSON (application/json) for input and output
> 

]FIG]


[FIG(quote)[
[FIGCAPTION[
[59] [CITE[Microsoft REST APIガイドラインはRESTfulではない]]
([TIME[2016-08-07 22:45:37 +09:00]])
<https://www.infoq.com/jp/news/2016/07/microsoft-rest-api?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_news_clk>
]FIGCAPTION]

> Microsoftが「RESTful」なAPIを作成するためのガイダンスを公開した。Roy Fielding氏は、そのAPIを (RESTとほとんど関係ない) HTTP APIと見なしている。

]FIG]


[FIG(quote)[
[FIGCAPTION[
[62] [CITE@ja[RESTful Webサービスの開発]]
([TIME[2011-05-20 09:55:34 +09:00]])
<https://docs.oracle.com/cd/E23549_01/web.1111/b61390/rest.htm>
]FIGCAPTION]

> Representational State Transfer(REST)は、SOAPなどの追加メッセージング・レイヤなしで、標準化されたインタフェース(HTTPなど)を介してデータを送信する単純なインタフェースを記述するものです。RESTには、ステートレス・サービスを作成するための一連の設計ルールが用意されており、これらはリソース(特定の情報のソース)として表示されます。それぞれのリソースは固有のURIで識別できます。クライアントがURIを使用してリソースにアクセスすると、標準化された固定のメソッド・セットと、リソースの表示が返されます。クライアントは、新しい各リソース表示を使用してステートを転送します。

]FIG]


[FIG(quote)[
[FIGCAPTION[
[64] [CITE@en[GitHub GraphQL API | GitHub Developer Guide]]
( ([TIME[2016-12-21 11:10:41 +09:00]]))
<https://developer.github.com/early-access/graphql/>
]FIGCAPTION]

> Rather than construct several REST requests to fetch data that you're interested in, you can often make a single call to fetch the information you need.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[69] [CITE[Simple API]]
( ([TIME[2017-06-06 07:41:05 +09:00]]))
<https://castingwords.com/docs/developer/SimpleAPI.html>
]FIGCAPTION]

> The API is RESTish. The goal is not to follow REST's practices closely, but rather to make an easy API to get up to speed with using a dynamic language or curl. 

]FIG]
