公司项目用了 RESTful 感觉很坑,请教一下后端前辈



自己总结了几个遇到过的比较困扰的情景:



网友评论:
spring boot + datatable控件,如reactTable
pass POJO in requestBody

发自我的iPhone via Saralin 2.0.1
来自: iPhone客户端

DELETE /api/goods?index=object_index
把参数带进去啊,参数用JSON格式

POST /api/order/
{new_order_content_in_json_format}

不同操作不要用magic number,用不同的endpoint,每次修改不用参数,直接post一个diff

GET /api/members?user_ids=[list_of_user_ids]

有这么一个表格,内容包括总部名下的所有超市,这些超市的会员总数,这些超市消费量前三名的会员名称,这些超市的上级供货商的名称、联系方式、公司名称和公司地址,这些超市当日销售额、当月销售额、年度销售额以及它们的环比增幅。以上所有数据分布在十二张表上,还有一些需要从第三方的接口查询。
怎样把这个接口设计成资源?

先把资源拆分啊,你这么多东西放在一起做什么?RESTful要配合microservice来做。不同的表在不同的endpoint上,然后再建一层逻辑统一调用这些endpoint。性能有问题就上cache


复杂查询怎么写?

假设一个宠物店管理系统,在系统的不同地方有许多个宠物列表,它们分别支持不同的筛选排序方式,包括:
按照上一次来店检查的时间排序
按照宠物曾在本店治疗过的疾病筛选
按照主人的姓名、手机号码排序
按照主人本年度在店消费额区间筛选
按照宠物的昵称模糊匹配
按照宠物血统起源国分组
按照宠物的毛色多选筛选(杂毛有多个毛色选项)
按照宠物的种族多级批量筛选(伴侣动物->猫->进口->俄罗斯蓝猫 + 鸟类->鹦鹉->澳洲->玄凤鹦鹉)

这些条件都是这个接口的参数吗?
GET /api/pets

不一定要用参数,我个人觉得MongoDB基于javascript的查询语法比较有用。
玩过RESTful,不好玩

强行用http的 GET PUT DELETE来表示增删改查我觉得是闲的

我向来推荐怎么方便怎么来,自己玩得爽就好,不要到处乱找一些奇怪的条条框框把自己束缚住

不要用自己的风格带坏标准。RESTful设计至少在思想上在处理大型项目的时候很有帮助。
复杂查询什么的直接走GraphQL呗,没必要用一大堆查询endpoint和magic number...

—— 来自 Essential Products PH-1, Android 9上的 v2.1.0-play
restful只是一种风格 不是标准 接口约定好就行
按照restful的理念
要获取的话就要用GET
要上传的话就要用POST
太死板了

GET /api/members?user_ids=4&user_ids=8&user_ids=79&user_ids=104&user_ids=77&user_ids=44&user_ids=8944
这种URL谁也不想见到

何不用POST /api/member/filter 把筛选条件变成JSON对象 POST上去再慢慢解析
WEB开发中,使用JSON-RPC好,还是RESTful API好?
http://www.zhihu.com/question/28570307/answer/541465581

量力而行,不要强上restful,很容易两头尬
你的需求 graphql 比较合适
Restful 是种风格,不是标准。你就是不用restful风格,上面的问题你依然会面对。就像楼下说的,参数可以用JSON封装。
不用非要用restful,那个只适用于简单的crud,很多复杂的操作没办法表现的
RestFul主要适用于db资源的CURD,很多动作是没法用rest表示的。。
不操作数据库你用restful你是不是铁憨憨

  -
不死搬教条啊

8楼说的不错,其实你将各种比较复杂的操作整体当作一个资源来看待就很容易转过弯了
贵司的userid是不是应该考虑用字符串

— from OPPO PAAM00, Android 8.1.0 of Next Goose v2.1.2


离开ee开发多年,原来restful没有只停留在学术上,。。

我记得restful风格接口是给资源provider组织暴露自己资源访问方式比较清晰明了的风格,在暴露资源的时候,还没有后端或前端的设计,总之就是先暴露了(项目可能是分开的,资源方的项目就是提供接口为止,调用又是另外的项目,或另外一批项目,或干脆就是公共服务->不特定多数应用程序调用)。如果你是数据库/资源库,前端后端一块设计,不一定要用restful。
资源方在设计restful风格接口的时候,根本没有预见应用程序如何调用它们,也不该预见,他应该以最范化的思维方式进行设计,以满足最大公约数的调用需求,而不考虑特定业务。所以作为特定应用程序,直接调用是困难的,需要先做一次封装。
真诚建议看看 paypal 的 api 设计规范,基本上是市面上最全面的 restful 接口设计指南了,你的这些问题在它的 pattern 里都能找到方案。http://github.com/paypal/api-standards


批量删除接口怎么写?
http://github.com/paypal/api-st ... .md#bulk-operations

================================================

订单状态流转怎么写?

订单状态流转实际上是用户对订单执行了某种操作,状态变更是操作的结果。订单操作并非只是变更了订单状态,很多时候还会涉及其他状态、关联资源的变更。
订单的某个状态字段的变更是你的具体实现,不应该暴露给用户,并且不同的操作也不可能只靠变更一个状态就能实现,将这些复杂的逻辑都揉在一个接口里,是一种 bad smell。
所以应该暴露的是封装后的订单操作。
比如,支付订单:/v1/orders/{order_id}/pay,实际上这个操作不只是变更了订单状态为 PAID,还涉及财务、仓储等内部逻辑。
http://github.com/paypal/api-st ... ontroller-resources

================================================

结果筛选怎么写?

两种都可以,看你喜欢。
?status=CLOSED&status=INVALID 这种方式 http 天然支持解析为数组,但比较啰嗦;
?statuses=CLOSED,INVALID 这种需要自己做一下解析,但 url 可以短一些
http://github.com/paypal/api-st ... ame-query-parameter

================================================

所有接口都能设计成资源吗?

资源的设计是跟着你的需求来的,restful 与 DDD(领域驱动设计)关系很近,识别领域资源不仅仅是接口设计的问题,而是整个系统设计的问题。

================================================

复杂查询怎么写?

复杂查询单独写一个 search 接口,通过 POST 提交查询参数。比如你的例子:
POST /v1/pet-store/pets-search
{
        "treated_diseases": ["Lymphoma", "Psittacosis"],         // 按照宠物曾在本店治疗过的疾病筛选
        "annual_spending": "10000-15000",                                         // 按照主人本年度在店消费额区间筛选
        "nick_name": "旺财",                                                                 // 按照宠物的昵称模糊匹配
        "lineage": "US",                                                                         // 按照宠物血统起源国分组
        "hair_colors": [],                                                                         // 按照宠物的毛色多选筛选(杂毛有多个毛色选项)
        "categories": [1153, 1154],                                                 // 按照宠物的种族多级批量筛选(伴侣动物->猫->进口->俄罗斯蓝猫 + 鸟类->鹦鹉->澳洲->玄凤鹦鹉)
        "sort": "owner_name|asc, owner_phone_no|desc",                 // 按照主人的姓名、手机号码排序
}

http://github.com/paypal/api-st ... ex-operation-search
一个功能要接口调用一次完成保持原子性,不要分步
那就不要用呀,反正restful是一种风格,改起来也很方便,我觉得后端接口还是看成“远程函数调用”比较合适

谢谢,很有启发性


我全用post,参数全部在json,然后不同的功能不同的接口(甚至对于列表功能,有分页和无分页我也要分两个接口)。
我特别讨厌在url的查询参数区放东西……

—— 来自 Xiaomi Mi Note 2, Android 8.0.0上的 v2.1.2


业务都封装在JSON里,基本只用POST或GET

高级语言的话json基本都是要转换成类的,接口协议设计就是类设计

标签: 用了   发布日期:06-25