您的位置:首页 > 其它

RESTful API 设计最佳实践(8)

2017-02-28 00:40 501 查看
前面几篇文章介绍了一些RESTful API设计方面的参考规范,这篇文章我们来看几个“不良”的例子,并以个人的实践总结为这一系列做个结尾。欢迎大家评论交流。

一、几个“不良”示例

1. 查询当前活动状态

** 请求:**
GET /activity/query?method=status&game=PDK&type=a
Accept:json

** 应答:**
{:status-code 200
:body { status : 当前活动状态close/open}


点评: 只是去掉了rpc的外壳包袱,可以在浏览器中直接查了,但method=status这种格式是典型的rpc。

2. 玩家领取活动礼包

** 请求:**
POST /activity/package
User-Agent: 浏览器信息
Cookie: token=XXXXXXXXXXXXXX
Accept:application/json; charset=UTF-8
Content-type: application/x-www-form-urlencoded; charset=UTF-8
body: username=aa&name=”礼包名称”

** 回应:**
{status-code: 201 // 领取成功
body: { name : “礼包名称”
msg : “*******”}}


点评:(1)客户端发送数据选择了application/x-www-form-urlencoded格式,而不是更为广泛使用的json或edn格式。 (2)为某个玩家增加一个礼包,应该为:

POST /activity/users/{user-id}/packages/{package-name}

3. 根据牌局信息查找对应的牌局ID(UUID)

** 请求:**
GET /games/game-id/{qijuid}/{username}/{gamesign}
Cookie: token=XXXXXXXXXXXXXX

** 回应:**
{status-code: 200
body: “fds4324324gfdfds324d /nil (如果没有,返回nil)”


点评:

(1)这里要获取的资源是game-id,过滤条件是qijuid、username、gamesign,所以,应该设计为:

GET /games/game-id?qijuid={qijuid}&username={username}&game-sign={game-sign}.

(2)game-id不存在时,不应该返回nil 而是返回404.

(3)如果没有特殊需要,统一返回JSON或EDN。

4.1. 获取单局牌局录像信息

** 请求:**
GET /games/record/game-id
Cookie: token=XXXXXXXXXXXXXX
Accept:json

** 回应:**
{status-code: 200
body: {record: JKJKDJFSFDSJK…. //牌局记录信息}


4.2. 获取单局牌局分享信息

** 请求:**
GET /games/game/game-id
Cookie: token=XXXXXXXXXXXXXX
Accept:json

** 回应:**
{status-code: 200
body: {id: 牌局ID
username: 分享者ID
flower: 12345
time: 分享时间
desc: 分享者分享时的描述}}


点评:

牌局记录信息只是牌局分享信息中的一个属性,分成两个接口获取是非REST的。在资源定义时,牌局这一资源(包括上述所有信息)应该是暴露给外部的,可以统一用一个API解决。

如,获取牌局录像:

GET /super-star/games/:game-id?fields=record

获取牌局所有分享信息:

GET /super-star/games/:game-id

二、总结

总的来说,当前我们对RESTful API的设计与服务的实现可能存在以下几个方面的不足:

还是以RPC的思想来设计RESTful API和REST服务。最明显的表现是,习惯性在设计API时使用“根据XX得到XX”,这是典型的RPC设计,针对过程,而非资源。

对“资源”来抽象服务的这种形式理解不到位。还是会将资源对应为一个过程产生的值。

在设计资源关系的API时,处理不正确,参考上述例子。

对于什么时候该用查询参数,什么时候将“变量”写到基本URI中不太清楚。

开发流程有问题,先根据初步设计API,再实现,再修改API,导致API设计妥协于实现。但REST服务的实现应该是RESTful API驱动开发的,类似于测试驱动开发。

API的设计和REST服务妥协于实现/现实。

时间压力:要实现一个真正的REST服务,实现其灵活性和可扩展性,相对于那种RPC式的开发可能要花费更多的时间,比如要支持查询参数灵活变动、自定义排序、自定义所需的资源属性等。

三、个人REST实践流程总结

第一步:定义资源(REST中资源是粗粒度的),使用“资源”来抽象整个服务(一定是资源!千万不要陷入“根据什么来获取什么”的思路中!),确定哪些资源需要暴露给外部,资源的具体属性可以先不细致确定。

第二步:设计RESTful API,对第一步定义的资源进行标识,并确定其资源表述格式,包括header(如支持的媒体类型,content-type等)、body。比如确定哪些资源是支持通过查询参数自由过滤的,那些是支持自由指定返回的资源属性的,哪些是整个资源全部返回的;成功时的状态码,异常时的状态码及异常消息格式等。

第三步:针对API进行实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  restful api设计 总结