不转移版本 v1 的询问用户列表的 API,肯定会有部分用户依照不是你预期但是你开放的接口去行使这么些框架

统一筹划三个好的框架和统一筹划3个好的软件一样,要求考虑的上面许多,比如扩大性、品质、用户体验、稳健性等等,视不一致的景色,种种点都恐怕导致成败,但她俩平时并不是业主们关怀的,因为在多数情形下,他们日常都不曾达成极限的渴望,只怕说相比较工作以来,一台机器不够上两台、十台不够上百台,没什么大不断的,反正花的都是客户的钱。当然作者无论理论上照旧履行中都不赞同那一个意见,但多少时候也只可以俯首称臣,所以就本文而言,那几个都不是非同平常。

能源路径

RESTful API 的统一筹划以资源为骨干,每3个 URubiconI 代表一种能源。因而,UCR-VI
无法包罗动词,只好是名词。注意的是,形容词也是足以使用的,不过尽量少用。一般的话,不论能源是单个依然多少个,API
的名词要以复数进行命名。别的,命名名词的时候,要运用小写、数字及下划线来区分三个单词。那样的设计是为着与
json
对象及品质的命名方案保持一致。例如,一个查询系统标签的接口能够拓展如下设计。

【GET】  /v1/tags/{tag_id} 

与此同时,财富的路线应该从根到子依次如下。

/{resources}/{resource_id}/{sub_resources}/{sub_resource_id}/{sub_resource_property}

大家来看一个“添加用户的剧中人物”的统一筹划,当中“用户”是主能源,“剧中人物”是子能源。

【POST】  /v1/users/{user_id}/roles/{role_id} // 添加用户的角色

某个时候,当一个能源转移难以使用标准的 RESTful API
来定名,能够考虑选拔部分特殊的 actions 命名。

/{resources}/{resource_id}/actions/{action}

举个例子,“密码修改”这几个接口的命名很难完全采纳名词来创设路径,此时能够引入
action 命名。

【PUT】  /v1/users/{user_id}/password/actions/modify // 密码修改

洋洋洒洒扯了半天,今后说说API的归类,经常来说,全体可以被用户直接待上访问到的程序接口、配置文件、环境变量、插件规范依旧是网卡新闻等等只要跟框架相关的都足以算是API。虽然除了程序接口外那个的API并不是看起来那么的分明性,但是她们的基本点其实不用程序接口低,甚至还有恐怕比程序接口的副效用更要紧,比如假若我们有个控制报文类型的参数,01意味着呼吁,02意味着应答,并且当前唯有那俩种取值,某个用户或然会if
(packetType.equals(“01”)) … else
…,这样就给系统的存续衍生留下了后患,因为背后大概会衍生出03代表广播,同时把01的意义修改为P2P请求,纵然01本人含义没有爆发变化,但总体的业务范围扩展了,所以对于这么些非程序接口的API,同样需求不多不少的对外祖父开该公开的。其次,对于众多参数来说,假如从上下文能够演绎出客观的默许值,就不要强制用户去挑选,因为假诺你将该参数设置为可选之后,意味着用户有权不爱抚该参数、越来越多的情景则是用户压根不想关注该参数,他们期待她们运用的框架提供了创造的私下认可值,比如在头名的数额库oracle/mysql/postgresql中,具有多量的参数、优化增选,但在切切实实中应当来说十分九上述的种类都运作于暗中同意参数的景况,这些中相当大片段又是直接利用了安装程序自带的以身作则配置,假设程序常常不平静,那正是框架的题材,若是在有个别环境有毛病,那正是环境的标题,用户平素都不会觉得作者不驾驭,所以不安定,在本人接触过的大方开发人士、维护人士中,只有极个其他百分比认为是不打听程序、框架天性和适用条件恐怕导致的系统不安宁。所以,就那一点而言,假设您不愿意您付出的框架被弃之不顾,除了提供成功的手册告诉用户他们有权本人主宰之外,还必须本身去充实依据上下文总计出客观的您留给用于优化依然保安指标的参数。特别是在程序语言本人会给相应的变量赋予暗中同意值的事态下,有个别特别不小概到了运维是才会接触,对于取值0、1,true、false那些值,甚至很有恐怕程序运转了数个月未来出现了1个一点都不大概解释的bug,而以此bug正是出于作者把接纳权交给了用户,而用户并没有采纳导致的。

万分响应

当 RESTful API 接口出现非 2xx 的 HTTP
错误码响应时,选用全局的不行结构响应音讯。

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "code": "INVALID_ARGUMENT",
    "message": "{error message}",
    "cause": "{cause message}",
    "request_id": "01234567-89ab-cdef-0123-456789abcdef",
    "host_id": "{server identity}",
    "server_time": "2014-01-01T12:00:00Z"
}

对此众多一回性的品类依然当中系统的话,平常叁次开发用户并不多,提供给终端用户的接口日常也是UI层做了严峻的卷入,所以用户一般不会有太多的机会直接绕过界面访问到系统的脆弱之处。但框架的生命周期平时要比这几个种类要长得多,并且在其生命周期中,一个接口或然插件或者会经历数十竟然上百次升级和周密,比如很多常见利用的开源类库大小版本加起来某些照旧有好几百次。试想,若是那个类库对于常用的接口没有仔细的卷入和对固然的防御性爱慕,导致用户有意仍旧无意的运用了小编本不期望用户使用的接口,进而导致笔者无法从API包容的角度公布下一本子,那该是多么的垮台。。固然从可能率的角度来说,那些不希望被违背使用的接口的可能率占据全体接口的比例很低、并且她们平日是被高级用户所运用,但那一个接口经常比较主要而且会严重危机到软件持续的升级换代。由于框架涉及的面很广,通常会有成都百货上千生育系统运营在其上,并且随着业务的开拓进取,会光顾在框架上的各类新的要求、甚至和原性格相互冲突的急需,此时,一旦有些接口被依照非预期的方法利用了,要想收回来改变其实现已展开衍变就很难了,要想完成随心所欲地依照小编的安排举行发展,首先必要器重的一点事绝不让用户接触到不想让他俩接触的,而不是由此条例大概须要让她们依照的信守。就算我们兴许编写了宏观的用户手册、注意事项,绝当先一半的用户好像都未曾只怕不太喜欢去读书手册和readme,这点在软件行业,小编发现开发人士是最不爱好阅读文书档案和各样资料的,反而是系统一管理理员和DBA倒是挺喜欢钻研的。

规划一套精美的 API 接口。
原文地址:服务端指南
| 优良的 API
设计指南

博客地址:http://blog.720ui.com/

有关那样做的资金财产和低收入,恐怕大部分的项目CEO、部门COO和开发人士都并不在乎恐怕说没有测算过、甚至能够说不精晓什么计算,可是那实际上深远的呈现了二个存在已久的定律–墨菲定律。可是笔者想,那多少个的确的我们称为程序员也好、架构师也好、亦恐怕技术专家认同,他们应该深谙其道、或者他们并从未下结论,只是无声无息在实践罢了。

三个整机的案例

最后,大家应用1个一体化的案例将前方介绍的知识结合起来。这里,使用“获取用户列表”的案例。

【GET】     /v1/users?[&keyword=xxx][&enable=1][&offset=0][&limit=20] 获取用户列表
功能说明:获取用户列表
请求方式:GET
参数说明
- keyword: 模糊查找的关键字。[选填]
- enable: 启用状态[1-启用 2-禁用]。[选填]
- offset: 获取位置偏移,从 0 开始。[选填]
- limit: 每次获取返回的条数,缺省为 20 条,最大不超过 100。 [选填]
响应内容
HTTP/1.1 200 OK
{
    "count":100,
    "items":[
        {
            "id" : "01234567-89ab-cdef-0123-456789abcdef",
            "name" : "example",
            "created_time": 1496676420000,
            "updated_time": 1496676420000,
            ...
        },
        ...
    ]
}
失败响应
HTTP/1.1 403 UC/AUTH_DENIED
Content-Type: application/json
{
    "code": "INVALID_ARGUMENT",
    "message": "{error message}",
    "cause": "{cause message}",
    "request_id": "01234567-89ab-cdef-0123-456789abcdef",
    "host_id": "{server identity}",
    "server_time": "2014-01-01T12:00:00Z"
}
错误代码
- 403 UC/AUTH_DENIED    授权受限

(完)

越多美丽小说,尽在「服务端思维」微信公众号!

论及API的向后兼容性,上个月又遇见个难题,API无论从二进制和接口规范上都早已形成了向后的合作,不过因为效益的恢宏,引入了额外的三方库,不过多少开发职员就是越发地不情愿引入额外的第二方库,理由是太大了,对此小编权且没有特意好的章程让开发人士心甘情愿的升迁,权且的措施是对此一些老版本存在的bug,老版本中不修复,仅在新本子中期维修复的不二法门来推进。

状态码

利用符合的状态码很重要,而不应当全套都回来状态码
200,或然随便乱使用。那里,列举小编在事实上开发进度中常用的一对状态码,以供参考。

状态码 描述
200 请求成功
201 创建成功
400 错误的请求
401 未验证
403 被拒绝
404 无法找到
409 资源冲突
500 服务器内部错误

在本文中,笔者想计算3个点,这些点很重庆大学不过又平常被忽视,很多不或许产品化可能最终费用高昂的系统有无数都以那或多或少造成的蹉跎,这么些点莫过于《软件框架设计的不二法门 》那本书里面一再在说,对于非纯正网络的软件商店来说,没有浓厚的会心那或多或少是那个店铺软件维护开支高昂的根本原因之一,这几个点便是API包容性的统一筹划。若是必要已经大约分明了,那么设计和贯彻就很重大,但比她们更关键的是小编要想通晓,希望用户怎样选拔,并单独且不多不少提供给用户你想让用户选用的,不然,肯定会有局部用户遵照不是您预期不过你开放的接口去采纳这么些框架,比如说,大家曾在贯彻1在那之中间件的时候,处于系统爱护目标的设想,大家渴求全数的用户定义接口的时候,必要带3个参数,同时最好继承框架提供的某部基类。于是,某一天,作者发现,用户越发扩充了限制,他们在事情封装的接口上如若了接口必须有参数,并且没有做防御性编制程序,最终造成出现了NullPointerException。还有一次,大家在统一筹划接口的时候,希望用户通过自行注入的方法去选择框架,但后边大家发现,用户在有点地点通过java反射的办法直接去赢得运转时实例,不过在此场景中,框架一开始安插的时候就高居管理的目标内部提供了对应的API,及时防患了用户通过狂暴的java
reflection实行揣测式的硬编码,为后续框架的嬗变及时解除了后患。

响应参数

本着差别操作,服务端向用户重临的结果应该符合以下标准。

【GET】     /{version}/{resources}/{resource_id}      // 返回单个资源对象
【GET】     /{version}/{resources}                    // 返回资源对象的列表
【POST】    /{version}/{resources}                    // 返回新生成的资源对象
【PUT】     /{version}/{resources}/{resource_id}      // 返回完整的资源对象
【PATCH】   /{version}/{resources}/{resource_id}      // 返回完整的资源对象
【DELETE】  /{version}/{resources}/{resource_id}      // 状态码 200,返回完整的资源对象。
                                                      // 状态码 204,返回一个空文档

如果是单条数据,则赶回1个对象的 JSON 字符串。

HTTP/1.1 200 OK
{
    "id" : "01234567-89ab-cdef-0123-456789abcdef",
    "name" : "example",
    "created_time": 1496676420000,
    "updated_time": 1496676420000,
    ...
}

假如是列表数据,则赶回多个包装的结构体。

HTTP/1.1 200 OK
{
    "count":100,
    "items":[
        {
            "id" : "01234567-89ab-cdef-0123-456789abcdef",
            "name" : "example",
            "created_time": 1496676420000,
            "updated_time": 1496676420000,
            ...
        },
        ...
    ]
}

恳请参数

在规划服务端的 RESTful API
的时候,大家还索要对请求参数进行界定表达。例如一个支撑批量询问的接口,咱们要考虑最大扶协助调查询的数码。

【GET】     /v1/users/batch?user_ids=1001,1002      // 批量查询用户信息
参数说明
- user_ids: 用户ID串,最多允许 20 个。

除此以外,在筹划新增或修改接口时,我们还索要在文书档案中分明告知调用者哪些参数是必填项,哪些是选填项,以及它们的边界值的界定。

【POST】     /v1/users                             // 创建用户信息
请求内容
{
    "username": "lgz",                 // 必填, 用户名称, max 10
    "realname": "梁桂钊",               // 必填, 用户名称, max 10
    "password": "123456",              // 必填, 用户密码, max 32
    "email": "lianggzone@163.com",     // 选填, 电子邮箱, max 32
    "weixin": "LiangGzone",            // 选填,微信账号, max 32
    "sex": 1                           // 必填, 用户性别[1-男 2-女 99-未知]
}

询问参数

RESTful API 接口应该提供参数,过滤重临结果。其中,offset
钦赐重临记录的发端地方。一般景色下,它会结合 limit 来做分页的询问,那里
limit 钦点再次回到记录的数据。

【GET】  /{version}/{resources}/{resource_id}?offset=0&limit=20

再者,orderby
能够用来排序,但仅协助单个字符的排序,尽管存在多个字段排序,需求工作中扩展其余参数实行支撑。

【GET】  /{version}/{resources}/{resource_id}?orderby={field} [asc|desc]

为了更好地挑选是还是不是援助查询总数,大家得以使用 count 字段,count
表示回去数据是不是带有总条数,它的暗中同意值为 false。

【GET】  /{version}/{resources}/{resource_id}?count=[true|false]

地点介绍的 offset、 limit、 orderby
是部分公共参数。其余,业务场景中还设有重重天性化的参数。大家来看一个事例。

【GET】  /v1/categorys/{category_id}/apps/{app_id}?enable=[1|0]&os_type={field}&device_ids={field,field,…}

瞩指标是,不要过度设计,只回去用户须要的询问参数。其余,需求考虑是不是对查询参数成立数据库索引以增加查询质量。

版本号

在 RESTful API 中,API
接口应该尽量合营此前的版本。但是,在实质上业务支付处境中,只怕随着业务要求的继续不停迭代,现有的
API 接口不能支撑旧版本的适配,此时假设强制升级服务端的 API
接口将造成客户端旧有成效出现故障。实际上,Web
端是布局在服务器,因而它能够很不难为了适配服务端的新的 API
接口进行版本升级,然则像 Android 端、IOS 端、PC
端等任何客户端是运作在用户的机械上,由此当前产品很难形成适配新的服务端的
API
接口,从而出现成效故障,那种意况下,用户必须升级产品到最新的本子才能平常使用。

为了消除那几个本子不兼容难题,在统一筹划 RESTful API
的一种实用的做法是应用版本号。一般景况下,大家会在 url
中保存版本号,并还要包容八个本子。

【GET】  /v1/users/{user_id}  // 版本 v1 的查询用户列表的 API 接口
【GET】  /v2/users/{user_id}  // 版本 v2 的查询用户列表的 API 接口

以往,大家能够不改变版本 v1 的询问用户列表的 API 接口的情形下,新增版本
v2 的查询用户列表的 API
接口以满意新的事务须求,此时,客户端的产品的新成效将呼吁新的服务端的 API
接口地址。即便服务端会同时协作七个版本,不过还要保障太多版本对于服务端而言是个相当的大的担当,因为服务端要保险多套代码。那种意况下,常见的做法不是保险有着的非凡版本,而是只保险最新的多少个分外版本,例如维护最新的八个地位非凡版本。在一段时间后,当超越一半用户进步到较新的版本后,吐弃一些使用量较少的服务端的老版本API
接口版本,并供给运用产品的尤其旧的本子的用户强制升级。

留意的是,“不转移版本 v1 的询问用户列表的 API
接口”主要指的是对于客户端的调用者而言它看起来是尚未变动。而实际上,如若事情转移太大,服务端的开发人士须求对旧版本的
API 接口使用适配器情势将呼吁适配到新的API 接口上。

伸手方式

能够由此 GET、 POST、 PUT、 PATCH、 DELETE
等措施对服务端的财富进行操作。当中,GET 用于查询能源,POST
用于创建财富,PUT 用于革新服务端的能源的满贯消息,PATCH
用于更新服务端的能源的一部分消息,DELETE 用于删除服务端的财富。

此地,作者利用“用户”的案例开始展览追思通过 GET、 POST、 PUT、 PATCH、 DELETE
等方法对服务端的能源进行操作。

【GET】          /users                # 查询用户信息列表
【GET】          /users/1001           # 查看某个用户信息
【POST】         /users                # 新建用户信息
【PUT】          /users/1001           # 更新用户信息(全部字段)
【PATCH】        /users/1001           # 更新用户信息(部分字段)
【DELETE】       /users/1001           # 删除用户信息