编程与软件工程github.com
微软 REST API 指南
Microsoft REST API Guidelines
2016 — 2019,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
微软官方的 REST API 设计指南,涵盖 URL 结构、HTTP 方法语义、版本控制、分页、错误处理等实践规范。这份文档多次登上 Hacker News,成为业界讨论 API 设计标准时常引用的参考。
为什么经久不衰:它把 HTTP 语义和 API 设计的最佳实践整理成清晰可查的规范,多年来一直被团队当作设计 API 时的对照基准。
HN 评论精选
强调各 HTTP 方法的语义与幂等性,尤其 PUT 必须幂等
每个写 REST API 的人都应该背下这张表:GET 返回对象当前值且幂等;PUT 替换对象或创建具名对象,幂等;DELETE 删除对象,幂等;POST 根据提供的数据创建新对象或提交命令,不幂等;HEAD 返回 GET 响应的元数据,幂等;PATCH 对对象做部分更新,不幂等;OPTIONS 获取请求相关信息,幂等。最重要的是 PUT 是幂等的。
jedberg查看英文原文
Every single person writing a REST api should have to memorize this table: GET - Return the current value of an object, is idempotent; PUT - Replace an object, or create a named object, when applicable, is idempotent; DELETE - Delete an object, is idempotent; POST - Create a new object based on the data provided, or submit a command, NOT idempotent; HEAD - Return metadata of an object for a GET response. Resources that support the GET method MAY support the HEAD method as well, is idempotent; PATCH - Apply a partial update to an object, NOT idempotent; OPTIONS - Get information about a request, is idempotent. Most importantly, that PUT is idempotent. Credit to arkadiytehgraet for retyping the table to be readable. Please give them an upvote for the effort.
REST 规范并非普适,金融等领域的业务天然不符合其假设
我设计过不少 REST API,但结论是这些语义/HATEOAS 等规范并非在所有领域都适用。我在金融行业设计 API 时,除了标准对象外,几乎所有数据和操作都不幂等、不可缓存,也无法用 HATEOAS 建模:报价和订单涉及随请求用户自动换汇的金额,报价因市场波动只有几秒到几分钟的有效期,也没有 PATCH/DELETE 式的对象修改,一切操作都记录在日志里。硬套这些规范只会得到复杂难读、性能更差的 API。
littlecranky67查看英文原文
I've designed quite some REST APIs, but I've come to the conclusion that all those semantic/HATEOS or other REST guidelines don't always apply or make sense, depending on the problem domain. I worked in finance and designed a REST API, and besides the standard user/account object, basically ALL the data and operations were neither idempotent, cacheable, durable and often couldn't possible be designed using HATEOS et al. Quotes, orders, offers and transactions carry lots of monetary amounts which are sent in user currency, which is auto-converted depending on the user requesting it (and currency conversion rates is part of the business). Most offers are only valid a limited amount of time (seconds to minutes) because of changing market rates. There is also no "changing" of object as in PATCH/DELETE, all you do is trigger operations via the API and every action you ever did is kept in a log (regulatory wise, but also to display for the end user). There is some way to try to hammer this thing to fit with HATEOS et. al. and I put some effort in it, but I would have ended up splitting DTOs into idempotent/mutable and non-idempotent/mutable parts and spread them across different services, bloat the DTOs themselves (i.e. include all available currencies in a quote/offer) and have the validity/expiry of objects via HTTP caching (instead of the DTOs). That would have ended up in a complex and hard-to-read API, would have significantly worse performance (due to lot of unneeded data & calculations) and some insane design decisions (like keeping expired offers/quotes around just so they are still available at their service URL with an id, even though the business requirements would never store expired offers). Sometimes you just need to use your own head, accept that the problem domain might not be covered by other "guidelines", and come up with a sane design yourself.
游标式分页优于 LIMIT/OFFSET,元数据应放响应头
分页是很多规范都搞错的地方。LIMIT/OFFSET 式分页会导致 O(n²) 的操作,自动化工具想拉取大集合全量数据时很糟糕。更好的做法是只返回指向'下一页'的不透明链接,用数据库可索引的字段做 seek 而不是偏移量,HTTP 甚至有为此设计的标准头。把元数据从响应体移到响应头,还能让返回的数据保持纯数组这一合理格式。
deathanatos查看英文原文
Pagination is one of those things I feel like so many of these things get wrong. LIMIT/OFFSET (or as MS likes to call it, TOP/SEEK) style results in O(n²) operations; an automated tool trying to pull the entirety of a large collection in such a scenario is not good. I have to again recommend the excellent "Pagination done the Right Way" presentation[1] from Use the Index, Luke (an equally excellent site). Just return a link to the "next page" (make the next page opaque); while this removes the ability to of the client to go to an arbitrary page on its own, in practice, I've never seen that matter, and the generalized URL format allows you to seek instead of by LIMIT/OFFSET by something indexable by the DB; HTTP even includes a standardized header for just this purpose[2]. I also think the generalized URL is more in line with Fielding's definition of REST, in that the response links to another resource. (I don't know if being in the header invalidates this; to me, it does not.) If you get the metadata out of the data section of your response, and move it to the headers, where it belongs, this usually then lets you keep the "collection" of items you are return as an array (because if you need to put metadata along side it, you need: { "the_data_you_really_want": [1, 2, 3], "metadata, e.g., pagination": {} } vs. ["the", "data", "you", "wanted", "in a sensible format"] ) (I've seen metadata-pushed-into-the-body turn API endpoints that literally need to return no more than "true" or "false" into object that then force a client to know and look up the correct key in an object… sigh.) [1]: http://use-the-index-luke.com/no-offset [2]: https://tools.ietf.org/html/rfc5988
指出指南遗漏了 REST 的核心 HATEOAS,JSON 并非理想的超文本格式
REST 的核心创新是 HATEOAS,而这份文档完全没提。JSON 不是超文本,它本来就不是适合 RESTful 服务的格式。难道没人注意到这一点吗?
vearwhershuh查看英文原文
The primary innovation in REST is HATEOAS (which isn't mentioned in the document at all.) JSON isn't a hypertext, it just isn't a good format for REST-ful services. http://intercoolerjs.org/2016/01/18/rescuing-rest.html http://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.html Doesn't anyone notice this? I feel like I'm taking crazy pills. https://www.youtube.com/watch?v=HOK6mE7sdvs
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选