全栈工程师修炼指南
熊燚(四火)
Oracle 首席软件工程师
32206 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 46 讲
全栈回顾 (1讲)
加餐 (1讲)
全栈工程师修炼指南
15
15
1.0x
00:00/00:00
登录|注册

05 | 权衡的艺术:漫谈Web API的设计

马丁·福勒的文章
学习其他网站的 Web API 设计
接口风格的权衡
总结设计步骤
响应和异常设计
消息正文封装
条件查询
角度二:接口粒度的划分
角度一:易用性和通用性的平衡
承载技术
需求和限制
API
Web API
定义具体接口形式
确定接口风格
结合实际需求和限制,选择承载技术
明确核心问题,确定问题域
Web API
API
扩展阅读
总结思考
定义具体接口形式
确定接口风格
结合实际需求和限制,选择承载技术
明确概念
设计步骤
概念
Web API 设计

该思维导图由 AI 生成,仅供参考

你好,我是四火。
今天,我们该根据之前所学,来谈谈具体怎样设计 Web API 接口了。我们围绕的核心,是“权衡”(trade-off)这两个字,事实上,它不只是 Web API 接口设计的核心,还是软件绝大多数设计问题的核心。
我们说“没有银弹”,是因为没有一种技术可以百搭,没有一种解决方案是完美的,但一个优秀的全栈工程师,是可以从琳琅满目的同类技术中,因地制宜地选择出最适合的那一个。

概念

在一切开始之前,我们先来明确概念。什么是 Web API?
你应该很熟悉 API,即 Application Programming Interface,应用程序的接口。它指的就是一组约定,不同系统之间的沟通必须遵循的协议。使用者知道了 API,就知道该怎样和它沟通,使用它的功能,而不关心它是怎么实现的。
Web API 指的依然是应用程序接口,只不过它现在暴露在了 Web 的环境里。并且,我们通常意义上讲 Web API 的时候,无论是在 B/S(浏览器 / 服务器)模型还是 C/S(客户端 / 服务器)模型下,往往都心照不宣地默认它在服务端,并被动地接受请求消息,返回响应。
通常一个 Web API 需要包括哪些内容呢?
回答这个问题前,让我们先闭上眼想一想,如果没有“Web”这个修饰词,普通的 API 要包括哪些内容呢?嗯,功能、性能、入参、返回值……它们都对,看起来几乎是所有普通 API 的特性,在 Web API 中也全都存在。而且,因为 Web 的特性,它还具备我们谈论普通 API 时不太涉及的内容:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Web API设计是一门需要权衡的艺术。本文从明确概念、设计步骤和接口风格三个方面介绍了Web API设计的核心内容。首先,Web API是应用程序接口的一种,暴露在Web环境中,需要考虑承载协议、请求和响应格式等特性。设计步骤包括明确核心问题、选择承载技术和确定接口风格。在选择承载技术时,需要考虑实际需求和限制,以及客户端的影响。接口风格的选择涉及易用性和通用性的平衡,以及接口粒度的划分。文章强调了权衡在Web API设计中的重要性,需要根据实际情况做出选择,同时也指出了在一些极端情况下可能需要牺牲一致性来保留冗余的情况。文章通过深入的技术分析和举例,展现了Web API设计的复杂性和挑战性。 文章还提到了REST风格下的参数传递方式,以及消息正文封装和响应与异常设计。此外,文章还引出了一些问题,如在REST设计中如何处理复杂行为,比如银行转账接口的设计。通过这些内容,读者可以了解Web API设计的关键步骤和技术要点,以及在设计过程中需要考虑的权衡和挑战。整体而言,本文为读者提供了深入的技术分析和实践案例,帮助他们更好地理解Web API设计的复杂性和挑战性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《全栈工程师修炼指南》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • panlatent
    置顶
    结合上一讲内容,想问问老师对 graphql 的看法,以及如何权衡 graphql / rest 两种api 。

    作者回复: 这其实是个很好的问题。 我对 GraphQL 的理解简单来说是这样的,仅供参考。它本质上是一种声明式的 DSL,把接口逻辑从服务端拿到客户端来,客户端来决定做什么查询,执行什么操作,资源的概念被彻底弱化了。 和基于资源的 REST 相比,因为可以更加细粒度地控制需要什么数据,减少了多次调用或者是不需要的数据返回造成的开销。当然,它也有许多弱点,比如复杂性更高(客户端需要理解复杂的业务数据模型),不容易使用缓存等等。 我觉得它应该是 REST 风格的一种补充,而不是绝对的替代。有很多场景,比如复杂的数据查询,使用 GraphQL 可以做得很灵活,且有比较高的效率。而多数业务场景,REST 确是更好的选择。

    2019-09-21
    10
  • tt
    置顶
    1、突然有个想法,通过路径传递参数相当于非web系统设计的定长报文或固定分隔符报文,可读性比较差,可以更多的实现对外部的信息隐藏。 而通过query参数传递相当于URL承载的键值对报文,可读性比较好。 实现上,通过路径传递的话,在后端实现url解析即请求路由的时候需要完成参数的判断,使用一些开发框架可能更简单,但是这个过程不是完全由实现业务的人来控制,是不是会影响整个系统的扩展性以及处理效率呢? 所以我觉得通过路径传递参数适合参数种类及个数比较少的情况, 2、对于银行转账如何用rest风格设计接口,我觉得可以用“变换”的思维,把转账这个动作“变换”或“视作”为一个创建一笔“转账”业务对象的操作,这个业务对象有若干属性,比如收付款账号、金额等,从而继续使用rest风格。 此外,老师有没有关于web api鉴权和授权方面的参考链接呢?

    作者回复: 感谢回答。 关于 1,我觉得你说得很好。路径传递“隐含”了这个 key,而使用 Query String 的键值对的方式,则显式指定了 key。从这个角度来说,确实后者更为“明确”。 但是,“可读性”并不一定是指定了 key 的更好,可读性毕竟是一个和个人理解密切相关的判断。通常在路径层次较短,且路径的定义符合人的认知的时候(比如“资源/分类/唯一ID”,这样由大到小的递进),路径传递参数的方式也具有很高的可读性。 在使用框架处理的难度方面,我认为这两种方式并没有太大区别。 另外,使用 Query String 的方式灵活性上要更高,比如可以通过合理的配置自动构造和注入一个复杂的参数对象,这方面我们会在下一章学到。 关于 2,说得非常好,这种把一个复杂行为转变为可进行 CRUD 的“资源”,就是一种很有效的处理方法。 对于你最后关于鉴权和授权的问题,我计划在第 5 章谈到。

    2019-09-20
    7
  • 饭团
    我感觉路径选择不够灵活,因为他默认了各级参数所对应的含义!在需要加入参数或者调整参数顺序的时候就会带来诸多不便!我看到的大部分对外接口都是在指定到特定目录后(应该是该功能的功能模块),参数通过或则query_string的形式传输过来! 也就是说如果一个接口使用纯路径选择,是不是就适合于功能较为简单,参数偏少的情况!而大部分情况都是混合使用

    作者回复: 👍,说得很好。

    2019-09-21
    6
  • alan
    老师,为啥说204是最常见的返回码?不是200吗?

    作者回复: 看场景了。对于 Web API 来说,如果是一个命令接口,常常见到返回 204,表示操作成功,但不需要消息体。

    2019-09-22
    2
    4
  • pyhhou
    1. 感觉有点类似大接口和小接口,把 category 放在路径上相当于小接口,因为我们可以分开考虑并实现不同 category 的 API 组,优点是从 URL 上面看比较直观;如果把 category 放在参数中,那么必须要先对 category 进行判断后,再进行逻辑的拆分。对于参数值的种类不多,参数之间联系不多的情况,可以将参数放在路径上面,参数值的种类多的情况可以考虑放在 query_string 上,实际设计的话可以两者搭配使用 2. 如果要使用 REST 也是可以使用的,可以考虑将这个转账的行为进行抽象,比如用一个 unique ID 表示用户执行的操作是 “转账”,然后带上相关数据。总之是让客户端和服务器达成一个共识 API 设计经验不多,说的不好的地方还请老师指出 这一章学完,了解了很多自己之前没有接触过的概念,感觉这一章总体来说理论偏多一些,想要学得更加透彻肯定还是需要自己下去多动手尝试,可能现在学的东西只是一些知识点,需要跟完整个专栏,然后有一定经验后才能横向对比,对某些层面的东西才会有更深的认识,这也是一个过程,慢慢来吧

    作者回复: 👍

    2019-10-01
    2
  • paperen
    1.在介绍 REST 的参数传递的时候,我们讲了 category 参数传递的两种方式,一种是通过路径传递,一种是通过 Query String 的参数传递。你觉得哪些参数适合使用第一种,哪些参数更适合使用第二种? ———————————— 好像要从产品角度来分析,路径传递觉得适合那些能归总为“大类”或“页面”的模块 例如:图书类别(点击类别进入到该类别图书的页面),某个出版社页面(进入该指定出版社的页面) 而querystring方式适用在某个“大类”页面筛选器,例如:在某个类别页面再筛选作者叫johnson的图书 2. 我们要给银行转账,即钱从一个人的账下转移到另一个人的账下,这样的复杂行为不属于增删改查中的任何一项,我们是否能使用 REST 风格来设计这样的转账接口呢? ———————————— 可以的 我觉得rest风格是相对宽松的,不一定非要对得上增删改查,更多的在于定义了操作的粒度引发在业务层面上对主体的划分,比如干脆为转账这个动作使用POST并定义为交易中的一种:trade/transfer POST

    作者回复: #1, 这个方式挺好 #2, 把行为变成一种资源,就可以应用REST风格了

    2020-05-29
  • leslie
    问题、技术、风格和定义:这个似乎不止在web api的设计中会有这个问题,我觉得在现在的数据系统/存储中间件 的设计中其实现在典型的出现了;毕竟现在一旦设计软件就不是过去传统的C/S或B/S。 昨天一个同行问我一个问题:我们有前端开发,我们需要架构师;我就反问了一句“你们需要的是什么架构?”分析"问题"、寻找“技术"、选择“风格”、定义"需求"。架构师这个已经有点泛泛了:就像全栈一样,好的全栈其实才是一个好的架构师-他能权衡从前端-开发-数据系统-网络设计。各种模块的权衡才是最困难的事情;老师觉得呢?其实很多架构师都是有明显的缺陷的。 老师说权衡的艺术:其实好的全栈才能成为一个好的架构师,否则我们只能去说软件架构、数据系统架构、网络及安全架构;老师怎么看?

    作者回复: 这个问题太大,不是很好回答。个人觉得这两个概念基本上还是在两个不同维度上,不是很适合放到一起比较。:)

    2019-09-23
  • 编程爱好者
    全栈工程师不是技术方面的问题,而是灵魂是否有趣的问题,很喜欢作者结尾分享的链接,这门课程是告诉我们如何成为一个有趣的程序员

    作者回复: 感谢评价!

    2019-09-20
    2
  • huihui
    四火老师推荐的Any API 这个很不错,很赞!
    2019-10-10
    2
  • 会飞的鱼
    点赞👍
    2020-03-27
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部