RESTful API 设计最佳实践(8)

前面几篇文章介绍了一些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进行实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值