Restful API 设计(二)

智码寻幽使
• 阅读 1444

2015年冬天,我写下第一篇也是目前唯一一篇关于 Restful API 设计的文章。时间过的飞快,转眼三年前过去了。这三年间经历过的项目中,后台逐渐微服务化,restful 也成为大家耳熟能详的设计方案。这里记下些自己的经验和教训,以供对照。

Status code

基本的 code 原则很简单,2xx 表示成功,4xx 表示客户端错误,5xx 表示服务端错误。

那如何分辨是客户端还是服务端错误呢?我总结了以下几种常见的客户端错误,以及对应的错误码。

  • 401 - 未授权的访问比如访问资源需要 token 鉴权,如果不携带 token 或者 token 已过期,则返回 401.
  • 403 - forbidden,禁止访问。比如某些资源只允许管理员访问,非管理员则返回 403。
  • 404 - not found,不存在。

总之,凡是客户的锅,都返回 4xx 。如果恰好不在上面所列的三种情况中,则用 400 代替。

服务端自身错误则包含两类情况:

  • io 错误,比如读写文件,访问数据库
  • 自身逻辑错误,比如内存泄漏。

第一种错误是不可避免的,属于不可控的外部环境问题。第二种错误虽然可以通过 review 代码加上各种测试来预防,但最好有个兜底的错误处理以免程序挂掉。

我司对于服务端错误统一返回 500(internal server error),因为考虑到服务端错误对于客户来讲毫无建设意义,毕竟客户绝对没有办法帮助我们解决错误。即使对于工程师来说,日志也比 code 更有表现力。相对而言,客户端错误则尽量设计的详细因为大部分情况下客户端要据此来引导用户回到正常的业务中来。比如,如果返回 401,则引导用户登陆或者注册。如果业务比较复杂,还要考虑扩展 reponse 来指明更加具体的错误。如:

400 bad request
{
  "code": 123,
  "message": "Name is required"
}

List API

GET /orders

200 OK
{
 "offset": 0,
 "limit": 20,
 "count": 100,
 "elements": [...]
}

对于这个 List API,如果资源不存在,返回应该是什么。受 404 概念的普及影响,很多人会选择返回

404 NotFound

难道说,如果不存在 orders(订单) 就是错误吗?比如我从来没有在淘宝下过单,那订单列表也就应该显示客户端错误吗?这显然是不对的。实际上,404 是指所请求的资源不存在。而对于 orders 来说,它是一个集合概念。不管下没下过单,这个集合总归是存在的。按照这个理论,正确的返回应该是:

200 OK
{
 "offset": 0,
 "limit": 20,
 "count": 100,
 "elements": [] // 空数组
}

所以对于 List API 来说,没有 404。

Parent resource

restful API 的路径可以表现资源的从属关系。比如,用户可以有多个地址。

/users/{user_id}/addresses/

那么,对于一个并不存在的用户而言,访问上述 API,应该返回什么?

用户不存在,他的地址也必然不存在,那似乎是个简单的客户端错误。但我们确实有必要参考 Parent resource 的状态吗?这从理论上讲似乎毫无破绽,但实际操作及其困难。假如 Parent resource 的状态为 s1, Child resource 的状态为 s2,如果必须参考 s1 才能定义 s2,则 Child resource 的状态为 s1 s2。这还是简单的层次,如果 Parent 之上还有 Parent,则最终 Child 的状态会变成 s0 s1 * s2。如果随着业务的升级,每个节点的状态推算都要这样越来越复杂,那结果必然是整个系统的崩塌。

所以,目前比较推崇的做法是,仅仅考虑目标资源或者资源集合的状态。即,addresses,不管它从属于谁。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
REST架构指导方案
REST架构指导方案\TOC\何为REST在2014年之后,社区中关于RESTFUL风格的文章开始渐渐多起,大多数RESTFUL的文章都是在阐述一种HTTPURL路径的写法风格。简单总结来说,这些文章归纳的点主要是:1.URL路径应该是名词而非动词。2.通过HTTP几个动词:GET,POST
Stella981 Stella981
3年前
Android 面试必备
前言时间飞逝,转眼间毕业两年多,从事Android开发三年了。我在想,也是时候将自己的Android整理成一套体系。这一次的知识体系图谱只涉及到Android基础知识部分和设计模式的,Android写这一套Android面试必备系列文章的初衷。1.整理自己学过的知识,总结,让其成为一套体系,方便日后查阅。2.现
Stella981 Stella981
3年前
RESTful API教程:学习关键的Web服务设计原则
!(https://oscimg.oschina.net/oscnet/3c978d628a8749d698f49982d5f724a8.jpg)本文为翻译发表,转载需要注明来自公众号EAWorld。作者:CameronMcKenzie译者:白小白原题:RESTfulAPIstutorial:Lear
Stella981 Stella981
3年前
RESTful API 设计最佳实践
WebAPI近几年变得越来越火,而简洁的API设计在多后端系统交互应用中也变得尤为重要。通常,会使用RESTfulAPI来作为我们的WebAPI。本文介绍了几种简洁RESTfulAPI设计的最佳实践。使用的名词而不是动词使用名词来定义接口!(https://static.oschina.net/uploads
Stella981 Stella981
3年前
RESTful API 设计实践
RESTfulAPI为网络应用程序设计提供了一套统一、合理的风格。它只是一种风格,而不是标准,所以也就没有一套统一的标准去规范化这些设计,本文从实践的角度出发,讨论RESTfulAPI设计上的一些细节,探讨如何设计出一套好用、合理、精炼的API。版本按照RESTfulAPI的风格,不同版本的API应该是同一种资源的不同表现
Stella981 Stella981
3年前
RESTful API 设计指南
  作者: 阮一峰(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.ruanyifeng.com%2F)  网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。  因此,必须有一种统一的机制,方便不同
京东云开发者 京东云开发者
10个月前
【原创】【深入浅出系列】之代码可读性
原创声明:该文章是个人在项目中亲历后的经验总结和分享,如有搬运需求请注明出处。这是“深入浅出系列”文章的第一篇,主要记录和分享程序设计的一些思想和方法论,如果读者觉得所有受用,还请“一键三连”,这是对我最大的鼓励。一、老生常谈,到底啥是可读性一句话:见名知
京东云开发者 京东云开发者
10个月前
【原创】【深入浅出系列】之代码可读性
原创声明:该文章是个人在项目中亲历后的经验总结和分享,如有搬运需求请注明出处。这是“深入浅出系列”文章的第一篇,主要记录和分享程序设计的一些思想和方法论,如果读者觉得所有受用,还请“一键三连”,这是对我最大的鼓励。一、老生常谈,到底啥是可读性一句话:见名知
设计团队管理经验总结
写这篇文章不是说我有多大能耐,只是想总结一下这几年的管理经验。我也拜读了一些企业高管的理念结合自己的实际来写这篇文章。<br前方高能预警,这是一篇很长的文章~希望对还没有形成自己管理体系的设计师有所帮助。不想成为设计总监的设计不是好设计,
liam liam
1年前
RESTful API 设计教程
RESTful架构基础,代表表现层状态转移(RepresentationalStateTransfer),长久以来一直是API服务的圣杯,最初由RoyFielding在其博士论文中定义。尽管它不是构建API的唯一方法,但由于其广泛的普及,即使是非开发者也对
京东云开发者 京东云开发者
10个月前
【原创】【深入浅出系列】之代码可读性
原创声明:该文章是个人在项目中亲历后的经验总结和分享,如有搬运需求请注明出处。这是“深入浅出系列”文章的第一篇,主要记录和分享程序设计的一些思想和方法论,如果读者觉得所有受用,还请“一键三连”,这是对我最大的鼓励。一、老生常谈,到底啥是可读性一句话:见名知