RESTful API 设计实践指南

RESTful API 设计实践指南

在移动应用异常火爆的今天,对移动应用的开发也如火如荼地进行着。

API架构在移动开发过程中已经成为不可或缺的一部分。其中RESTful API 目前可以说是最成熟的一套API设计理论了吧。

本人从事移动应用的开发过程中,结合网上一些大神的文章,加上自己对RESTful的理解和思考,也想分享一下个人的实践经验,回报社区,希望能帮到大家。

其实,对于restful的一些基本设计,可以直接参考阮一峰的RESTful API 设计指南,写得很清晰明白。但是真正实现起来可能会碰到一些具体的问题,如果没有更深入的理解往往处理起来会有些麻烦。

一、 资源有多种拥有另一种资源的情况如何处理?

我们都知道restful的一个重要原则就是:每一个URI代表一种资源。

假设现在有这样一个需求:获取学生收藏的歌手接口

根据阮一峰的文章我们很可能就设计成这样:

get:/students/:studentId/singers

如果学生和歌手之间只有这一种关系的话,没什么问题。但是,学生和歌手多一层关系怎么办呢,比如:学生讨厌的歌手

这个时候,我们就照成了困难。所以当两个资源有多种关系的时候,我们要讲关系也转换成实体,这个时候就是这样:

get:/students/:studentId/CollectedSingers
get:/students/:studentId/HatedSingers

这样做还有一个好处,那就是我们对这个新的实体也能有一些更新等操作,比如:讨厌的歌手,我们有讨厌程度,我们要设计接口修改讨厌程度

put:/HatedSingers

其实,到这里有过关系型数据库设计经验的同学能看出来,这种资源实体就对应了数据库中的关系表。基本上restful的实体设计对应数据库的表就没什么问题。

二、什么时候传递id,什么时传递实体?

get自然不用多说,本身不提供传递对象的能力。删除的时候,往往我们并不知道实体的具体信息,如果要专门建立一个对象,有点脱裤子放屁的感觉。

所以我的想法是:get/delete统一传递id进行操作,post/put直接传递完整实体。

三、获取某实体包含的实体详情如何设计?

举个例子,现在想要获得学生收藏的歌手信息。如果不仔细思考,很有可能就设计成这样:

1. get:/students/:studentId/collectedSingers/:singerId

但是,你仔细想想下,如果要获得歌手详情,要学生id干嘛,直接这样就可以了啊:

2. get:/singers/:singerId

所以,是描述不清晰,应该是获得学生歌手的收藏信息,应该是这样:

3. get:/students/:studentId/collectedSingers/:collectedSingerId

在仔细一想,不对啊,如果获取收藏信息我直接就这样了:

4. get:/collectedSingers/:collectedSingerId

乱了,理一理。

首先,2和4很好理解,就是一个返回歌手详情,一个返回收藏详情,这两个是不同的实体。

3这个并不存在,一旦/collectedSinger/:collectedSingerId已经能描述清楚意图,/students/:studentId就没有意义。

1是什么情况的,他描述的是student和singer的一种关系,他应该代表根据singerId和studentId查询出收藏详情返回collectedSinger这个实体。

同样的,删除/增加也是一样的道理。

四、批量修改某实体包含的实体如何设计?

换一个标题也一样:如何理解“put:/students/:studentId/CollectedSingers”?

不管是传递singer实体,还是传递collectedSinger实体,都可以用如下接口替代:

put:/singers
put:/collectedSingers

所以,只能有一种理解,那就是修改student和singer的收藏关系,修改student的收藏列表,也就是批量修改收藏,业务中也经常会有这种需求。

所以我这样理解:传入singer列表,批量修改学生的收藏。

五、如何设计让实体执行某个动作?

比如:被点赞次数是某个歌手的属性,如何设计?很容易我们会这样设计:

put:/singers

修改歌手就行啊,但是我们怎么知道现在服务器端这个歌手被点了几次?所以行不通。

那么我们创造一个实体来执行这个行为:

post:/singers/:singerId/star

通过这个star实体来承载点赞的行为。

具体实践

以上几个问题搞明白之后,基本就没什么设计障碍了,以下,我列出一个完整的接口设计,并给每个接口做了详细解释。

get:/students/:studentId   //获得某个学生详情
get:/students   //获得学生列表
post:/students   //新建一个学生
put:/students   //修改学生信息
delete:/students/:studentId   //删除某个学生

get:/singers/:singerId   //获取某歌手详情
get:/singers   //获取歌手列表
post:/singers   //新建一个歌手
put:/singers   //修改歌手信息
delete:/singers/:singerId   //删除某个歌手

get:/students/:studentId/CollectedSingers/:singerId    //通过学生id和歌手id获取收藏信息
get:/students/:studentId/CollectedSingers   //获取学生的歌手收藏信息列表
post:/students/:studentId/CollectedSingers //学生收藏一个歌手
put:/students/:studentId/CollectedSingers //传递singer数组,修改学生收藏的歌手列表
delete:/students/:studentId/CollectedSingers/:singerId //通过学生id和歌手id移除学生和歌手的收藏关系

get:/collectedSingers/:collectedSingersId   //获取收藏信息
get:/collectedSingers  //获取收藏信息列表
post:/collectedSingers  //增加一个收藏
put:/collectedSingers  //修改一个收藏
delete:/collectedSingers/:collectedSingersId  //删除一个收藏

post:/singers/:singerId/star   //给歌手点赞

实际接口开发中,根据业务需求,我们并不需要每个接口都实现,往往有些并不需要。但是,只要遵从这个设计规则,一旦有业务需求,我们也能完美处理,和扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值