【译】究竟什么是RESTful风格的编程?

首先要说的是,这是来自stackoverflow的一个高票答案(提问的问题就是我这篇翻译的标题),其次就是这个回答有点偏离正题,可是不影响咱们对RESTful的理解,最起码让我走出了一个误区,这里强烈推荐另一篇文章:我是咋向我老婆解释REST滴,看的茅塞顿开有没有!!html

原文连接web


REST是web世界的基本架构原则,关于web最神奇的事就是:明明以前客户端对服务器以及服务器资源一无所知,客户端(浏览器)和服务器却可使用复杂的方式来相互做用 。而关键的约束就是服务器以及浏览器客户端都在使用媒介上达成一致,而在web里咱们都知道这个媒介就是HTML。数据库

因此,坚持使用REST原则的API是不要求客户端了解该API的任何结构滴!相反,服务器会提供全部客户端与服务器交互所须要的消息,一个HTML的表单就是很好的例子:服务器指定资源的位置,以及须要的字段信息。浏览器不须要提早知道去哪里提交信息而且浏览器也不知道提交什么信息,这两种表单信息都是彻底由服务器提供的(这种原则就被称为HATEOAS)(译者注:HATEOAS是Hypermedia As The Engine Of Application State的缩写)。json

因此这货是怎么用在HTTP,咱们又怎么在实践中使用呢?Https是面向动做(verb)和资源(resource)的,我以为几乎全部的人都知道常常用的两个动做就是GET和POST,可是实际上HTTP标准还定义了其余的一些动做好比DELECT和PUT,这些动做根据服务器指令规定也会做用在资源上。api

好比,如今咱们想象有一个web服务在管理着一个数据库,咱们的服务是基于自定义的JSON,所以咱们定义一个application/json+userdb((这里也许还有application/xml+userdb 以及application/whatever+userdb - 许多的媒体类型都是支持的),服务器以及客户端的程序被写成了都能理解这种格式,可是相互之间没有任何联系,正如Roy Fielding指出的:浏览器

一个REST API应该把全部的精力都放在定义被用在表示资源和驱动应用状态的媒体类型(media type)上边,或者是为已经存在的标准媒体类型定义扩展的关系名以及超文本标记服务器

一个对基本资源“/”的请求可能返回一些下边这样的:restful

request:架构

GET /
Accept: application/json+userdb

response:app

200 OK
Content-Type: application/json+userdb

{
    "version": "1.0",
    "links": [
        {
            "href": "/user",
            "rel": "list",
            "method": "GET"
        },
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

根据media的描述咱们能够从部分被称为连接的部分上获得一些关于资源的信息,这被称为超媒体连接。在这种状况下,咱们被告知了能够经过造另一个连接“/user”来找寻一个user列表:
request:

GET /user
Accept: application/json+userdb

response:

200 OK
Content-Type: application/json+userdb

{
    "users": [
        {
            "id": 1,
            "name": "Emil",
            "country: "Sweden",
            "links": [
                {
                    "href": "/user/1",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/1",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/1",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        },
        {
            "id": 2,
            "name": "Adam",
            "country: "Scotland",
            "links": [
                {
                    "href": "/user/2",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/2",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/2",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        }
    ],
    "links": [
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

咱们从这个连接里又被告知了许多的东西,好比,咱们知道咱们能够经过POSTing这个“/user”来建立一个user:
request:

POST /user
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Karl",
    "country": "Austria"
}POST /user
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Karl",
    "country": "Austria"
}

response:

201 Created
Content-Type: application/json+userdb

{
    "user": {
        "id": 3,
        "name": "Karl",
        "country": "Austria",
        "links": [
            {
                "href": "/user/3",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/3",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/3",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

咱们一样知道了能够改变现有的数据:
request:

PUT /user/1
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Emil",
    "country": "Bhutan"
}

response:

200 OK
Content-Type: application/json+userdb

{
    "user": {
        "id": 1,
        "name": "Emil",
        "country": "Bhutan",
        "links": [
            {
                "href": "/user/1",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/1",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/1",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

注意咱们使用的不一样的动词(GET, PUT, POST, DELETE etc.)来操纵资源,固然咱们假设客户端的部分只有咱们的media定义

深刻阅读:
Martin Fowler's thoughts
Paypalde API | has hypermedia controls

(这篇文章由于其主观性而备受批评,而大多数的批评都是得当的,我以前的回答彷佛更偏向与Rest是如何在头几年实施的而不是如今你们看到的,我已经修改了答案使之更符合题目)编辑于1月18号

相关文章
相关标签/搜索