最近准备重写公司一个旧项目,每次想起这个项目,内心总忍不住要吐槽一波,难受。具体细节就不说了,水平不一样,见仁见智,也不是本文的重点。就是此时,技术leader说要把接口设计成RESTful规范,我拒绝了
,这东西适合当前业务开发吗?先后端对接麻烦吗?前端
这东西之前上学时就据说过,但工做也没看见有人彻底以此设计web
我也想遵照这传说中的规范,可现实不容许啊json
REST(Representational State Transfer),直译为表现层资源转换,具体就不说了hhh,相关文章一大堆,但REST感受没有一个十分明确的标准,更趋向于一种接口设计风格
,按照基本的约束条件进行开发设计。后端
有人说RESTful API能够一会儿让别人知道这个url是干什么的,但说到底不就是取决于咱们的接口命名吗?接口作到见名知义
,用良好的英文命名,不也能达到效果。因此,参考业界部分规范,我定义了以下命名。api
拿通用的订单模块举例,最基础无非是两种场景-获取列表
or 获取详情
数据结构
/api/order/orderList
/api/order/orderInfo
前面不加get?架构
以前我也加,时间久了总以为碍眼hhh,这里定义get,service层又定义一个相同或差很少的方法名,总以为在 重复命名
。为了让接口路径更短更精简,干脆省略get,后面就约定以 list/info结尾
就认为是获取数据信息了。
不学RESTful在数据实体后加s表示复数?app
对于后端 数据结构
而言,List更合适有些前端须要作列表展现,List翻译后更 见名知义
以s结尾的单词需加es就不说了,有些单词是单复数同行,若是加s我会以为这人英文语法不行啊,不加又像单数。因此为了统一,List最好
有时咱们的核心业务需求不定,相同的实体信息在不一样场景须要提供不一样的数据,其实到咱们后端就是根据不一样过滤条件查询出实体信息,有些所谓的RESTful规范说是在url后加参数信息,如:编辑器
/orders?state=finish&userId=123
url
这也是我不喜欢RESTful的缘由之一,某些场景下,过滤信息是固定不变的,不能经过前端传参决定
,并且url后带参数的传参也有弊端。
回到不一样场景不一样命名,最好能从产品用户角度
出发,好比:
/api/order/myAllOrderLIst
/api/order/finishiedOrderLIst
/api/order/invoiceOrderList
若是作后台管理系统这种项目,确实能够用list、info、save、update、delete一把梭了。每一个数据实体一定要有这些方法
myBatis-plus封装好了一些service、mapper方法,增删改查都有十分规范的命名。并且在相同的操做都有适合本身的命名。
动做 | service | mapper(dao) |
---|---|---|
增 | save | insert |
删 | remove | delete |
改 | update | update |
查 | get/list | select |
有些接口须要兼容不一样的APP版本,若是增长字段不能知足,无可奈何需增长新的请求路径,可加个v一、v2版本前缀
,原接口名不变,加个版本前缀还能够看到接口的历史修改,方便维护。
/api/order/v1/orderInfo
/api/order/v2/orderInfo
除了场景的GET、POST请求注解,Spring还有@PutMapping 、@PatchMapping、 @DeleteMapping 注解,标识不一样的请求方式。
不只如此,SpringMVC还支持参数绑定。
@RequestMapping(value = "/orders/{id}", method = RequestMethod.GET)
public void getById(HttpServletRequest request, @PathVariable("id") Long id){
System.out.println(id);
}
复制代码
这....又给咱们提供一种获取参数的形式..............
既然拒绝了RESTful,那咱们规定,前端统一用json形式POST请求接口传递参数,后端拦截器拿到请求,自定义ApiRequst类,将请求信息(请求头/请求体)统一封装,这样先后端架构都保持统一,更有利于联调。
@Data
public class ApiRequest implements Serializable {
private String appVersion; //请求头-app版本号
private Integer deviceType; //请求头-设备类型
private String deviceName; //请求头-设备类型
private String secret;
private String token;
private Map data; //请求体-业务参数
}
复制代码
Controller层统一形式接收
/**
* TestApi
* @param apiRequest
* @return
*/
@PostMapping(value = "/testList")
public ApiResponse testList(ApiRequest apiRequest) {
Long id = apiRequest.getDataParamAsLong("id", 0L);
String name = apiRequest.getDataParamAsString("name", "");
return ApiReponse.ok();
}
复制代码
其实我不并反对RESTful
,仅仅想说出本身的想法。存在即合理嘛。我也曾经尝试过其规范,真是一把辛酸泪。我以为只有适合本身的业务,能提升开发效率、先后端沟通效率的,就是良好的规范,规范并无一个十分统一的参考
。
咦,好像还漏了接口返回结果Response没说吧,这在RESTful里貌似也有说起。