V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Yelp
V2EX  ›  程序员

求教一个 API 设计难题

  •  
  •   Yelp · 2021-04-13 09:52:20 +08:00 · 2470 次点击
    这是一个创建于 1339 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在写一个应用,涉及到几个外部数据源的操作,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 创建一个用户

    11 条回复    2021-04-13 12:23:12 +08:00
    doublleft
        1
    doublleft  
       2021-04-13 10:12:43 +08:00
    如果都是操作 data-source 的话,可以加个类别

    例如:/data-source/detail/1 、/data-source/types 、/data-source/init
    baiyi
        2
    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
        3
    baiyi  
       2021-04-13 10:32:04 +08:00   ❤️ 1
    @baiyi #2 补充一点,我看的一本关于 RESTful API 的书里吐槽过这个解释,因为这个 “data-handling process” 含义太过模糊,所以现在有人的接口设计为全用 POST,其实也是符合 HTTP 语义的,因为任何操作都能引申为数据处理......
    no1xsyzy
        4
    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
        5
    opengps  
       2021-04-13 11:09:02 +08:00
    POST +header 或者 body 里传参
    SuperMild
        6
    SuperMild  
       2021-04-13 11:28:38 +08:00
    RESTful 表面上看起来优雅,但真的不好用(不容易用好),用起来很烦。

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

    因此我觉得 GET /data-source-types 就很好,语义非常清晰,也没有比 GET /data-source/types 更长(长度一样)。缺点只是从 RESTful 的角度看不够优雅(我个人认为那种优雅带来的麻烦比好处多)。
    mlcq
        7
    mlcq  
       2021-04-13 11:32:20 +08:00
    @SuperMild #6 你这样不方便权限控制
    blackboom
        8
    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
        9
    arthas2234  
       2021-04-13 11:53:56 +08:00
    我就喜欢在接口名字上尽量把用途体现出来。这样就很直白,看接口名就知道做什么的,并不需要再去看参数列表
    SuperMild
        10
    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
        11
    cmdOptionKana  
       2021-04-13 12:23:12 +08:00 via Android
    @SuperMild 不对,你想错了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5406 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 122ms · UTC 03:02 · PVG 11:02 · LAX 19:02 · JFK 22:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.