每个网络应用程序 - 每个网站 - 都是一项服务。 (...) 使网站易于网络冲浪者使用的功能也使 Web 服务 API 易于程序员使用。
Richardson 和 Ruby,“RESTFul Web 服务”
正如我所希望的那样,同时也是 Web 服务的网站提供其资源的多种表示形式,具体取决于用户代理的请求。可以说,API 就是网站本身,不单独提供。
对于许多流行的“REST API”来说,情况并非如此。例如,Twitter 的 API 位于http://api.twitter.com/1/ http://api.twitter.com/1/,URI 中的“1”是 API 本身的版本。 Socialcast 还提供了 REST API,位于https://demo.socialcast.com/api/ https://demo.socialcast.com/api/,第三级名称是其寻址的网络的名称。
这对我来说似乎是错误的。如果我的博客位于http://www.example.com/blog http://www.example.com/blog,我不需要在不同的位置提供 API,只为机器人提供 JSON。而不是有http://www.example.com/blog/posts/ http://www.example.com/blog/posts/ and http://api.example.com/blog/posts http://api.example.com/blog/posts,两个不同的 URI,我应该只有前者,并且有多种可用的表示形式,其中application/json
对于我希望提供给我的用户的 JSON API。
实施例1:浏览器询问我博客上的帖子;
Request:
curl -i \
-H "Accept: text/html" \
-X GET \
http://www.example.org/blog/posts/
回复:
200 OK
Content-Type: text/html; charset=utf-8
<html><body><h1>Posts</h1><ol><li><h2>My first post ...
实施例2:相同的 URI,但这次是机器人发出请求;
Request:
curl -i \
-H "Accept: application/json" \
-X GET \
http://www.example.org/blog/posts/
回复:
200 OK
Content-Type: text/html; charset=utf-8
{
"posts": [
{
"id": 1,
"title": "My first post" ...
API 的版本号应编码在请求标头的“Accept”字段中,最重要的是避免像 Twitter 那样强类型化 URI(“statuses/show.json?id=210462857140252672”或“statuses/show/210462857140252672.json” ”)。
采用统一方法可能会失去一些灵活性(但是,不应该很酷的 URI 永远不会改变? http://www.w3.org/Provider/Style/URI.html),但我认为坚持 REST(或者至少是我对它的解释)会带来更多好处。
哪种方法更正确:将 API 和网站分开,还是将它们统一?