求教一个 API 设计难题

2021-04-13 09:52:20 +08:00
 Yelp

最近在写一个应用,涉及到几个外部数据源的操作,API 设计上有一些矛盾,大家觉得哪种好,还是有其他的设计?

  1. 创建数据源
POST /data-source
  1. 获取支持的数据源类型列表
// 感觉 URL 太长
GET /data-source-type

// 跟 GET /data-source/{id} 重叠了
GET /data-source/types
  1. 提供连接参数,检测数据源是否可用
POST /data-source-check
POST /data-source?action=check
  1. 创建之前初始化数据源,比如创建 MySQL 表
POST /data-source-init
POST /data-source/init
POST /data-source?action=init

总结来说就是 对象未创建之前进行的一些操作怎么设计,比如:

检查用户是否存在 vs 创建一个用户

2442 次点击
所在节点    程序员
11 条回复
doublleft
2021-04-13 10:12:43 +08:00
如果都是操作 data-source 的话,可以加个类别

例如:/data-source/detail/1 、/data-source/types 、/data-source/init
baiyi
2021-04-13 10:29:23 +08:00
在 URL 的设计上我觉得能够语义清晰就可以了。

“获取支持的数据源类型列表” 我认为两种设计都可以,甚至 `GET /data-source?filter=types` 这样也可以,都是表达只获取 types 。

但 “提供连接参数,检测数据源是否可用” 我认为不应该用 POST 方法,ping 这种行为在我看来应该是安全且幂等的,应该用 GET 方法。所以这里合适的设计应该是 “GET /ping-data-source”

在我看来你的思考矛盾主要在于:你认为 HTTP Methods 都是针对资源的操作,而这个资源又被局限于实体存在的资源。
但这个资源实际上可以是抽象的、动态的,比如说用 RESTful 风格设计最常见的问题就是 “登录” 这个接口如何设计。其实只需要 `POST /login` 就可以。从 HTTP POST 方法本身的语义讲,是完全支持这样做的,它并不是单纯的用于创建资源的语义。rfc 文档中关于 POST 能力的部分解释:“Providing a block of data, such as the fields entered into an HTML form, to a data-handling process;”
baiyi
2021-04-13 10:32:04 +08:00
@baiyi #2 补充一点,我看的一本关于 RESTful API 的书里吐槽过这个解释,因为这个 “data-handling process” 含义太过模糊,所以现在有人的接口设计为全用 POST,其实也是符合 HTTP 语义的,因为任何操作都能引申为数据处理......
no1xsyzy
2021-04-13 10:55:21 +08:00
1. POST /data-source
2. GET /data-source/_types
3. POST /data-source/_ping
4. POST /data-source/_initialization

用 _ 来表示 meta 操作,是完全可理解、且常规的。而且越不常见的操作名字应当越完整、最好长得多。
但是令我迷惑的是,为什么会有单独的 4. 操作?不应该 1. 操作时直接做掉吗?
opengps
2021-04-13 11:09:02 +08:00
POST +header 或者 body 里传参
SuperMild
2021-04-13 11:28:38 +08:00
RESTful 表面上看起来优雅,但真的不好用(不容易用好),用起来很烦。

现在我的个人项目已经完全放弃 RESTful, 改成 GET POST 走天下。

因此我觉得 GET /data-source-types 就很好,语义非常清晰,也没有比 GET /data-source/types 更长(长度一样)。缺点只是从 RESTful 的角度看不够优雅(我个人认为那种优雅带来的麻烦比好处多)。
mlcq
2021-04-13 11:32:20 +08:00
@SuperMild #6 你这样不方便权限控制
blackboom
2021-04-13 11:50:50 +08:00
GET /data-sources

POST /data-sources/types
POST /data-sources/actions/check

不能使用 RESTful 表达的一律使用 POST 作为 “Function” 调用
arthas2234
2021-04-13 11:53:56 +08:00
我就喜欢在接口名字上尽量把用途体现出来。这样就很直白,看接口名就知道做什么的,并不需要再去看参数列表
SuperMild
2021-04-13 12:03:14 +08:00
@mlcq 权限控制不在这一层,因为楼主还有一个 GET /data-source/{id}, 因此 data-source 就只有一个,没有 data-source1 、data-source2 (因为那就应该是 /data-source/1 、/data-source/2)

因此只有一个全部数据源共用的 /data-source-types,不需要区分 /data-source1/types 、/data-source2/types
cmdOptionKana
2021-04-13 12:23:12 +08:00
@SuperMild 不对,你想错了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/770265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX