一声笑接口文档

2016-08-02  本文已影响19人  fight2048

title: 一声笑接口文档
date: 2019-03-03 21:44:43
tags:


Author:Leguang

E-Mail:langmanleguang@qq.com

目标

要求

命名规范

一名二姓三风水,四积阴德五读书,名不正则言不顺,言不顺则事难成。软件开发其实就是门命名的艺术,所以首先定义一些规范,提出一些硬性要求,大家在命名的时候尽量多花点心思,多参考优秀的命名风格。

uri规范

uri 表示资源,资源一般对应服务器端领域模型中的实体类,要求如下:

JSON规范

暂时只考虑json的数据格式,要求如下:

草稿:JSON返回的格式是分门别类按对象来划分,还是铺大饼的形式铺开,两者利弊各异,比如url,可能一个接口中返回多个url,如果分json对象装的话,则key都可以叫url,否则的话key就得命名成xxxUrl。这个有待商议

HTTP部分

使用场景

URL结构

https://{serviceRoot}/{module}/{collection}/{id}

公共请求头

通过Content-Type指定请求与返回的数据格式有JSON和XML,暂时我们只管json的。其中请求数据还要指定Accept。其中额外添加的请求头里的参数注意大小写。

Accept: application/json
Content-Type: application/json;charset=UTF-8
Token: token_G34G34G34G34G35G5
Application: 应用:版本
Platform: Android
Locale: zh
params 类型 是否必要 描述
Token String 这个不用解释了吧?
Application String App应用名称(名称有官方指定)与当前版本的版本名称,中间用半角冒号隔开
Platform String Android表示Android平台,iOS表示iOS平台
Locale String 用于针对接口的国际化,不同的值代表不同的语言,可以不传,不传默认表示中文简体。值和语言如下表所示:

暂时只考虑4门语言

意义
zh 中文(简体)
en 英文
ja 日文
ko 韩文

公共参数(部分公共参数建议公放到请求头里)

公共参数是指每一个接口都可能有的,为了减少篇幅,我在这里统一定义,同时后端要指定公共参数的默认值,且要保证没有传公共参数不会报错,所以需要一定的容错性,比如priceDes这个参数值,如果是用的是全部小写的,只要是不冲突,则可认为是准确的参数并且表达了按价格降序排列这个语意。常用公共参数如下:

params 类型 是否必须 描述
keyword String 用于检索,不传或者传空,表示默认,默认不检索该关键字
sort String 用于对列表排序,不传则表示默认,默认按配置顺序,asc升序,desc降序
page int 用于分页描述,不传则表示默认,默认是第1页
pageSize int 表示该页显示的条数,不传则表示默认,默认为20条

个性参数

个性参数就是除了公共参数之外的,看能否考虑统一用JSON将公共参数和个性参数浓缩成一个参数,把想要表达的参数通过json中的key-value形式传递。例如:https://api.xxx.com/both/v1/search/products?params={"extra":"你想填什么呢","token":"token_523523523","data":{"uid":"23523523523523"}} 或者考虑与业务相关的参数就用json形式包装,而与业务无关的个性参数就还是用传统的方式另立一个参数。例如:https://api.xxx.com/both/v1/search/products?limit=10&offset=10&params={"keyword":"方便面","sort":"des"}

通过商议将个性参数统一按原始的URL传参形式传递,不考虑上面所说的那种方式。

公共响应头

Content-Type:application/json; charset=utf-8
Status:200 OK

其中状态码要与公共响应体里的json中的code字段一样。

公共响应体

默认会有以下字段,不需要全部都有。

{
    "message": "居然被你查询成功了",
    "code": 200,
    "page": 0,
    "pageSize": 20,
    "first": "https://...",
    "next": "https://...",
    "previous": "https://...",
    "last": "https://...",
    "data": {
        "uid": "6565656565665"
    }
}
key 类型 是否必须 描述
message String 返回给接口调用者的描述,有可能用于显示到界面上,需要进行国际化处理
code int 这个与请求头中的状态码一致,是为了满足部分开发者的习惯
page int 分页请求中请求的当前页的页码
pageSize int 分页请求中一页的个数,默认为20
first String 分页请求中第一页的url ,如果没有则返回空字符串
next String 分页请求中下一页的url,如果没有则返回空字符串
previous String 分页请求中上一页的url,如果没有则返回空字符串
last String 分页请求中最后一页的url,如果没有则返回空字符串
data object 当前接口的具体数据由该json对象承载
uid String 对于每一个资源对象,在返回的时候,都应该返回操作这个资源对象的唯一码

HTTP动词表示操作。

常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

状态码

作为API的设计者,正确的将API执行结果和失败原因用清晰简洁的方式传达给客户程序是十分关键的一步。我们确实可以在HTTP的相应内容中描述是否成功,如果出错是因为什么,然而,这就意味着用户需要进行内容解析,才知道执行结果和错误原因。因此,HTTP响应代码可以保证客户端在第一时间用最高效的方式获知 API 运行结果,并采取相应动作。下表列出了比较常用的响应代码。
常用的http状态码及使用场景:

响应代码 代码含义
200 已创建,请求成功且服务器已创建了新的资源。
201 是否只显示处于警告状态的应用实例。
301 重定向 , 请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。
302 重定向 , 请求的网页临时移动到新位置,但求者应继续使用原有位置来进行以后的请求。302 会自动将请求者转到不同的临时位置。
304 未修改,自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。
400 错误请求 , 服务器不理解请求的语法。
401 未授权 , 请求要求进行身份验证。
403 已禁止 , 服务器拒绝请求。
404 未找到 , 服务器找不到请求的网页。
405 方法禁用 , 禁用请求中所指定的方法。
406 不接受 , 无法使用请求的内容特性来响应请求的网页。
408 请求超时 , 服务器等候请求时超时。
410 已删除 , 如果请求的资源已被永久删除,那么,服务器会返回此响应。
412 未满足前提条件 , 服务器未满足请求者在请求中设置的其中一个前提条件。
415 不支持的媒体类型 , 请求的格式不受请求页面的支持。
500 内部服务器错误。

分页

分页适用于GET类型且返回集合数据的请求,根据如下参数进行分页操作。分页返回的数据见公共响应体。

{
    "extra": "你想填什么就填什么",
    "page": 0,
    "pageSize": 20,
}
params 类型 是否必须 描述
page int 同上
pageSize int 同上

错误/异常处理

对第三点的实现稍微多说一点:

Java 服务器端一般用异常表示 RESTful API 的错误。API 可能抛出两类异常:业务异常和非业务异常。业务异常由自己的业务代码抛出,表示一个用例的前置条件不满足、业务规则冲突等,比如参数校验不通过、权限校验失败。非业务类异常表示不在预期内的问题,通常由类库、框架抛出,或由于自己的代码逻辑错误导致,比如数据库连接失败、空指针异常、除0错误等等。

业务类异常必须提供2种信息:

  1. 如果抛出该类异常,HTTP响应状态码应该设成什么;
  2. 异常的文本描述;
错误描述
{
    "message": "特么的又错了",
    "code": 500,
    "document": "https://developer.xxx.com/v1/errors/500",
    "exception": [
        {
            "code": "NullValue",
            "target": "PhoneNumber",
            "message": "Phone number must not be null"
        },
        {
            "code": "NullValue",
            "target": "LastName",
            "message": "Last name must not be null"
        },
        {
            "code": "MalformedValue",
            "target": "Address",
            "message": "Address is not valid"
        }
    ]
}
错误请求头
{
  "date": "Mon, 08 Jan 2018 03:07:08 GMT",
  "server": "nginx/1.10.3 (Ubuntu)",
  "connection": "keep-alive",
  "content-length": "237",
  "content-type": "application/json"
}

错误状态码(非200)

通过分析发现,接口的错误无非调用端传递给后台的信息与预期不符,其中包括公共参数和个性参数不符,不符包括缺失和内容错误(或格式错误等)两种,还有是部分特殊业务的特殊性质造成非正常结果,如:重复申请、重复签到等。经商议决定将错误码分为四大类:

错误码 类型 描述 举例
XXX int 用于描述缺少参数,同时message做出相应的辅助描述,告诉调用者到底是缺少哪个参数,这些message只有调用者看得到,用户看不到 需要a、b、c三个参数,结果只收到a和b参数,或者收到c参数,但c参数为空字符串,且c参数又是必传的,因此可返回该错误码,同时messgae中提示:缺少c参数,或者c参数不能为空
XXX int 用于描述有参数但参数错误,可能是内容错误或格式错误,同时message做出相应的辅助描述,告诉调用者到底是哪个参数错误,这些message只有调用者看得到,用户看不到 需要传a参数为String类型的11位手机号码,结果收到的是long类型,或只有10位的String,则可返回该错误码,同时message提示a参数错误
XXX int 描述某些特定业务场景,比如重复申请、重复签到等,每一个场景对应一个错误码,同时message会提示相应错误场景,这些message会给用户看到的 比如重复申请注册奖励,返回特定码,前端做出相应显示,或者跳转,或者隐藏即可
XXX int 描述某些公共功能,调用者会做出相应公共处理 比如token失效,直接跳转到登录界面

以上友好的message提示方便了我们,同时也方便了非法调用者,为阻碍非法调用,决定设置一个开关,该开关是系统自带的,根据编译环境变更,在调试阶段就用以上友好提示,在正式部署上线后就改成模糊提示。

url失效

随着系统发展,总有一些API失效或者迁移,对失效的API,返回404 not found 或 410 gone;对迁移的API,返回 301 重定向。

对于后台文档的要求

文档要求

文档要求描述详尽,尽可能的引导接口使用者理解接口设计,这样才能减少接口的改动,又能适应多变的业务。

容错性(健壮性)

考虑到如果测试或者运营中有变动,要求每一个Web页面得有容错机制,比如关停该功能,则web必须的有相应的页面展示。

国际化

此处的国际化是指语言的国际化,因此前后端都要考虑在界面的文字提示上要做国际化处理,暂时我们只做4种文字的国际化:中文(简体)、英文、日文和韩文,经商议,通过两方面来传递国际化信息:

由于有两个入口设置语言,因此有优先级处理,请求头中locale字段优先级大于locale设置接口,两者不传,默认都表示简体中文。locale接口默认为简体中文,如果有设置其他语言,则为其他语言,请求头里如果没有locale字段,则依据locale接口,如果请求头里带了locale字段,则依据请求头为准。

上一篇 下一篇

猜你喜欢

热点阅读