看了一堆的 Restful 的介绍 还是没太理解 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Renco
V2EX    程序员

看了一堆的 Restful 的介绍 还是没太理解

  •  
  •   Renco 2020-05-12 14:41:48 +08:00 5842 次点击
    这是一个创建于 2029 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对于我目前项目中的 请求地址

    /user/add 用户新增
    /user/delete 用户删除
    /user/pageQuery 用户列表拆线呢
    /user/detail 用户详情
    全是 post 请求,这种算是 Restful 风格嘛

    我查了下相关介绍
    GET /products : will return the list of all products
    POST /products : will add a product to the collection
    GET /products/4 : will retrieve product #4
    PATCH/PUT /products/4 : will update product #4

    大概是请求地址相同 然后是根据 GET POST PUT 这种做交互的才是 Restful 么

    37 条回复    2020-05-13 15:32:28 +08:00
    WittBulter
        1
    WittBulter  
       2020-05-12 14:55:30 +08:00
    1. 不算。
    2. 请求地址相同也不能严格的算 RESTful 。接口的方式变化只是操作资源的表达方式,并非是对 RESTful 的判断依据。

    不是你用上了 PUT PATCH 就是 RESTful,而是你使用资源的抽象方式的接口风格概括。建议可以学习一下 GitHub API v3 。
    Mithril
        2
    Mithril  
       2020-05-12 14:59:18 +08:00   1
    你这个显然不是。
    你说的请求地址在 RESTful 里面代表某种资源,通过不同的 HTTP 方法来表示对资源的操作。
    不过在实际项目里面并不会完全按照 RESTful 来设计全部 API 。总会在 RESTful API 和瞎胡搞 API 之间取得一个平衡。主要是全部用 RESTful 来做的话,有些逻辑就会变得很奇怪,而且很难设计。
    godgrp
        3
    godgrp  
       2020-05-12 15:01:23 +08:00
    不是单纯的请求地址相同哦,而是把请求的目标看作是一个资源,使一个请求更语意化。建议地址上尽量不出现动词,动作由 Http Method 来表达。当然这是一个理想化的约定,因为仅仅是个约定或者是规范,并不是一个协议,没有强制约束的。
    fengerzh
        4
    fengerzh  
       2020-05-12 15:02:20 +08:00
    不是。改成:

    GET /users 获取所有用户列表
    GET /users/1 获取单个用户详情
    POST /users 新增用户
    PUT /users/1 修改用户
    DELETE /users/1 删除用户

    这样才是 RESTful
    ericgui
        5
    ericgui  
       2020-05-12 15:09:03 +08:00   1
    GET /users 获取所有用户列表
    POST /users 新增用户

    你能分得清这俩 API 的区别么
    kiracyan
        6
    kiracyan  
       2020-05-12 15:59:58 +08:00
    感觉 RESTful 适合对外公用接口,让 API 调用者更方便使用,内部 API 感觉完全按照 RESTful 风格,有些接口会变得很奇怪,有完整的使用 API 文档是不是 RESTful 感觉应该没什么太大差别
    useben
        7
    useben  
       2020-05-12 16:03:22 +08:00
    @ericgui 所以是动作操作是通过请求方法来判断, url 只是表示资源
    EastLord
        8
    EastLord  
       2020-05-12 16:07:05 +08:00
    还有接口的返回格式
    strawberryBug
        9
    strawberryBug  
       2020-05-12 16:08:41 +08:00
    简单理解,REST 是一种理想化的约定,规范,实际设计 api 可以不按照这个来。REST 里 URL 路径代表对具体资源的访问,http 请求的方式代表对该资源的操作。

    比如 /users 这个路径代表的就是对 user 资源的访问,采用 get 请求就是获取用户信息,采用 post 请求就是新增。

    两两对比着看下面的例子。
    GET /users 获取所有用户列表
    POST /users 新增用户

    GET /users/1 获取 id 为 1 用户
    PUT/users/1 修改 id 为 1 用户信息
    taaaang
        10
    taaaang  
       2020-05-12 16:11:27 +08:00
    restful 还有个意思就是尽可能规范得设计 url, 使用 http 协议。
    VDimos
        11
    VDimos  
       2020-05-12 16:12:52 +08:00 via Android
    post 和 get 一把梭
    noobsheldon
        12
    noobsheldon  
       2020-05-12 16:29:00 +08:00
    wonderful, beautiful, restful
    lolizeppelin
        13
    lolizeppelin  
       2020-05-12 16:44:35 +08:00   2
    对外 url 表现,只是壳,所以你不理解

    包括外面的壳在内.服务端的代码和设计都是适合 restful 方式的才算 restful

    比如你可以参考 openstack 的 neutron,这个项目的就是完完全全的 restful
    但是 openstack 的 nova 就不是 restful

    一个原因是 nova 比较早,当时没有按照 restful 的方式设计,还有一个问题是 nova 的 api 不是那么适合完全用 restful 表达


    如果你的业务适合用 restful 表达..那么对外接口和代码设计上可以有很强的一致性
    否则,不应该被规范束缚,就像不应该完完全全用范式来束缚数据库设计一样


    其实之前论坛里有个人非常精准的形容了 restful对 sql 的劣质模仿
    0dJ6Tu8Za734L89T
        14
    0dJ6Tu8Za734L89T  
       2020-05-12 16:51:25 +08:00
    namelosw
        15
    namelosw  
       2020-05-12 16:55:30 +08:00
    1 不算,2 可以算 REST,但是这个是简单情况,后面有很多很难判断的,要把各种动作建模成资源。
    比如登陆不叫登陆叫 POST /sessions
    REST 看个基本就可以了,不用太纠结,很多东西用 REST 没法建模,比如搜索之类的。
    murmur
        16
    murmur  
       2020-05-12 16:57:20 +08:00   1
    实际开发中严格的 restful 反倒是撕逼的根源,大家的所谓 restful 都是留了后手的
    fkdog
        17
    fkdog  
       2020-05-12 16:59:30 +08:00
    一个资源设计风格而已。
    v2 上有的是这类把 restful 当成圣经一样跪拜的人。

    “你这 url 一点也不 restful,对不起我们不是一类人,我们追求不一样”。
    上述言论多见于一些毕业不过一两年的人。
    lookas2001
        18
    lookas2001  
       2020-05-12 17:11:01 +08:00 via Android
    @fkdog 我看了半天楼上的回复没看到你说的那一类人啊。

    回楼主,我的感觉 restful 就是从面向过程编程跃迁到面向对象编程。不是所有接口都能 restful,看着来吧。
    whusnoopy
        19
    whusnoopy  
       2020-05-12 17:29:36 +08:00   4
    在项目里尝试过,在 HTTP 时代被宽带运营商强 * 得不能自理,最后还是自己定义接口路径,并且全走 POST

    用 GET 的很多缺点

    1. 缓存。GET 请求在浏览器和运营商层面都会认为是不变的,那么是可以被缓存的,但是如果你修改了某个实体后,再 GET 这个实体,怎么保证能拿到的是新的?也可能你自己设置了合理的缓存时间,但是会被某些无良运营商缓存。这个要么就是加一个 `t=timestamp` 的随机串在后面避免缓存,但这样 GET 的意义是啥
    2. 无状态。按 Restful 的定义,GET 是无状态和幂等的,但是有些 GET 就是会影响其他数据,比如微博的阅读量被拿一次就应该加一,比如某些已读状态的标记,是从 GET 请求算,还是 GET 后客户端再 POST 或 PUT 一个请求来更新?只用 GET 就违反了无状态和幂等的原则
    3. 请求体大小。这个是早期浏览器的限制,GET 请求的请求参数不能超过 1024 个字节,如果遇上复杂一点的请求结构就挂了,还是只能走 POST
    Flywith24
        20
    Flywith24  
       2020-05-12 17:31:31 +08:00
    貌似 RESTful 没有 明确的定义?我的理解就是正确地使用 http
    dddd1919
        21
    dddd1919  
       2020-05-12 17:34:20 +08:00
    restful 宗旨是在请求的方式上体现你要做的动作,url 表名被操作的资源,类似动宾短语的意思

    比如
    要获取所有用户列表:GET /users
    获取用户 a 的信息 GET /users/a
    新建用户 POST /users
    更新用户 a 的信息 PUT /users/a
    删除用户 a DELETE /users/a
    stevenkang
        22
    stevenkang  
       2020-05-12 17:38:27 +08:00
    简单版:

    GET 查询数据,只读请求,支持幂等调用,对数据不产生任何影响

    POST 修改数据,增删改请求,对数据产生影响

    没有完全按照 RESTful 的规范来,但用请求 METHOD 区分一下,还是非常有必要的。
    passerbytiny
        23
    passerbytiny  
       2020-05-12 17:48:53 +08:00 via Android
    信息系统要想完整的用 RESTful,必须与领域模型结合起来。
    这些是面向资源库的操作,分别对应增加、删除、查询实体:
    POST /users
    DELETE /users/{id}
    GET /users?k=v&k=v GET /users/{id}

    这些是介于面向资源库和面向实体之间的操作,对资源库来说是修改指定实体,对实体来说是“维修”行为:
    PUT /users/{id} “整体换新”
    PATCH /users/{id} “换零件”

    前面的这些,基本上是通的。即使不是信息系统或者不使用领域模型,例如内容管理系统,当然最典型的还是万维网( www )资源体系,都是这样用(但是不同的背景有不同的具体含义)。而下面这些,则是领域模型专用的,并且是最主要的。他们面向实体,表示实体的一个行为:
    POST /users/{id}/eat
    POST /users/{id}/drink
    POST /users/{id}/shit
    POST /users/{id}/xuxu
    POST /users/{id}/sleep
    POST /users/{id}/... ...


    必须纠正一个误区,RESTful 不禁止动词。对于万唯网资源和内容管理系统来说,他们是只对资源做操作从而不会有动词,并不是禁止动词。而信息系统,不只是管理资源,还要支撑业务,是要用到动词的。

    手机敲字真累
    jswh
        24
    jswh  
       2020-05-12 18:21:23 +08:00
    RESTful 的核心是资源抽象,用 url 对应对应一个具体的抽象资源,目的是为了语义化(我看到 url 就知道啥意思,我想对一个资源做啥基本不用文档)。另外一个好处是通过 RESTful 可以表达资源之间的关系。狭义的 RESTful api 只是借用了 HTTP 的动词来做相关约定,基本上是约定俗成了。当然也可以不借用 HTTP 动词,用自己的动词形式:

    POST /products.retrieve : will return the list of all products
    POST /products.add : will add a product to the collection
    POST /products/4.retrieve : will retrieve product #4
    POST /products/4.update: will update product #4

    只不过这种私有私有约定并不友好。
    一个简单的判定是不是 RESTful 的方法就是,去掉了动词之后,剩下的 url 是不是你们业务中的一种资源的抽象。你的项目中的例子明显就违背了这一点。

    /user/pageQuery 用户列表拆线呢
    /user/detail 用户详情

    去掉了动词之后,都是 /user/,但他们明显不是一个东西。
    liangjx
        25
    liangjx  
       2020-05-12 18:34:45 +08:00
    @whusnoopy 老哥理解深刻
    stillyu
        26
    stillyu  
       2020-05-12 18:53:45 +08:00
    @lookas2001
    从面向过程编程跃迁到面向对象编程
    同意这个说法,运用了这个思想,url 和 http method 怎么定义,都可以团队内自己协商,也都算 restful
    SaigyoujiYuyuko
        27
    SaigyoujiYuyuko  
       2020-05-12 19:11:11 +08:00
    http 动词 + 资源
    S4msara
        28
    S4msara  
       2020-05-12 19:15:57 +08:00
    相同 path,不同 method,不同行为
    nutting
        29
    nutting  
       2020-05-12 19:18:47 +08:00
    我感觉最初就是 url 体现参数的一种风格
    hantsy
        30
    hantsy  
       2020-05-12 19:21:32 +08:00
    @jswh 不使用 Http Verb 就不能说是 REST API,你可以自称是 Web API 或者 Http API 。

    @Renco
    @WittBulter 其实自己的 REST API 质量很容易判断,可以自行搜索 Richardson Mature Model (网上介绍太多了),这是一个公认的判断 REST 质量的检测规则。自己比较一下自已设计的 API 到了哪个 Level,Level 2 以下的基本不叫 REST,Level 3 描述的 Self-documentation 特性是比较理想的状态(无需文档基础上可以清楚整个 API 的 schema 的树形结构),实际国外很多公开 API 都做到了( Github,Heroku 等)。国内大厂很多都是在 Level0,或者 Level1,V 站很多人在谈技术的时候往往不讨论技术本身,而是迷信某些大厂怎么做的,所以我一直觉得某些大厂把国内技术带歪了。

    另外, 国外已经有相当一部分 API 开始提供 GraphQL,GraphQL 违反 REST 一些设计规则,但是很好的解决 REST 在交换数据上颗粒度的问题。
    lewinlan
        31
    lewinlan  
       2020-05-12 20:45:47 +08:00 via Android
    在标准个瞎搞之间取得平衡+1
    至少做到利用 http 四个动词和状态码
    akagishigeru
        32
    akagishigeru  
       2020-05-13 08:25:38 +08:00 via iPhone
    这种当然不算 restful 只是一种标准而已 用不用是你的事儿
    looplj
        33
    looplj  
       2020-05-13 08:46:50 +08:00
    RESTful,本质上是使用资源的状态转移来实现业务,表现出来的形式就是对外暴露对资源的 CRUD
    如果,你的业务能用这种状态转移能表达,用还是很不错的,统一,标准
    ChanKc
        34
    ChanKc  
       2020-05-13 12:46:16 +08:00
    我觉得回帖中九成的人没有看到 restful 的本质。

    想一下你浏览 V2EX 的这个过程:你在浏览器输入 v2ex.com 或者从别的网站跳过来。服务器向你发送超媒体文本标记语言(也就是 html ),浏览器渲染后你可以看到这个帖子的链接,于是你知道你可以点这个链接从而看到这个帖子。作为人类你是自我驱动地去看到各种各样的超媒体(图片,链接,表单等等)并去获取各种各样你所要的信息。

    理想情况下的 restful 是这样子:你的客户端向 v2ex.com 请求(协议和方法不限),服务器响应的也是一个超媒体,包括一些信息和客户端接下来可以进行的行为。在“人类”的例子里就是 html 和<a>。你的客户端想要看关于 restful 的信息所以它请求了这个帖子的接口,从而获取到了信息。

    http 和 http 的方法只是方便了机器之间约定了请求的方法。但是 restful 可以不依赖于具体的网络协议和方法。如果服务器和客户端之间的交流是基于超媒体的,那么即便你全用 post 和 200 也可以是 restful api 。
    Yelp
        35
    Yelp  
       2020-05-13 12:48:36 +08:00
    请求方法对应 CRUD,然后参数合理放置:

    select * from users

    insert into users values(...users)

    select * from users where id = 1 limit 1

    update users set name = name where id = 1

    delete users where id = 1


    进阶:

    获取用户的收藏

    /users/:user_id/coll

    user = select * from users where id = 1 limit 1

    coll = select * from coll where user_id = user.id
    karlkor
        36
    karlkor  
       2020-05-13 15:14:12 +08:00
    RESTful 其实是一个没有固定规范的约定或者说命名风格,就像驼峰命名和下划线命名一样,语法上不是严格要求的,但是一般会遵循这种风格。
    比如 Python 里面定义一个变量 amount_of_apple = 10,当然也可以写成 amountOfApple = 10,解释器并不会报错,但是一般会按照第一种风格来写。同样的 HTTP 接口定义成 GET /object/1 或者 GET /object?id=1 都是可以解析的,但是设计接口的时候一般用前者多一些。
    no1xsyzy
        37
    no1xsyzy  
       2020-05-13 15:32:28 +08:00
    见到一说,就是在模拟(类比) Unix 文件系统
    GET /users = cat /users/*
    GET /users/1 = cat /users/1
    PUT /users/1 = echo ... > /users/1
    GET /users?name=John+Smith = grep "name: John Smith" /users/*
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     893 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 21:24 PVG 05:24 LAX 13:24 JFK 16:24
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86