微服务架构实战项目中接口的参数处理及统一结果响应

为了让读者更快地理解源码并进行个性化修改,接下来介绍项目中的接口是怎样处理参数接收和结果返回的。

  1. 普通参数接收

    这种参数接收方式读者应该比较熟悉,因为是 GET 请求方式,所以传参时直接在路径后拼接参数和参数值即可。

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiOperation(value = "商品列表", notes = "可根据名称和上架状态筛选")
    public Result list(@RequestParam(required = false) @ApiParam(value = "页码") Integer pageNumber,
                        @RequestParam(required = false) @ApiParam(value = "每页条数") Integer pageSize,
                        @RequestParam(required = false) @ApiParam(value = "商品名称") String goodsName,
                        @RequestParam(required = false) @ApiParam(value = "上架状态 0-上架 1-下架") Integer goodsSellStatus, @TokenToAdminUser LoginAdminUser adminUser) {
        // 省略部分代码
    }

    这段代码是商品列表接口的方法定义,格式为:

    ?key1=value1&key2=value2
  2. 路径参数接收

    在设计时使用了将部分接口参数拼入路径中的方式。当只需要一个参数时,可以考虑这种接口设计方式。与前文中的普通参数接收方式没有很大的区别,也可以设计成普通参数接收的形式,更多的是开发人员的开发习惯。

    @GetMapping("/detail/{goodsId}")
    @ApiOperation(value = "商品详情接口", notes = "传参为商品id")
    public Result<NewBeeMallGoodsDetailVO> goodsDetail(@ApiParam(value = "商品id") @PathVariable("goodsId") Long goodsId, @TokenToMallUser MallUserToken loginMallUserToken) {
    
        省略部分代码
    }

    这段代码是商品详情接口的方法定义,想要查询订单号为 10011 的商品信息,直接请求 /detail/10011 路径即可,代码中使用 @PathVariable 注解进行接收。

  3. 对象参数接收

    项目中使用 POST 方法或 PUT 方法类型的接口,基本上都是以对象形式来接收参数的。

    @ApiOperation(value = "登录接口", notes = "返回 token")
    @RequestMapping(value = "/users/admin/login", method = RequestMethod.POST)
    public Result<String> login(@RequestBody @Valid AdminLoginParam adminLoginParam) {
        // 省略部分代码
    }

    这段代码是管理员登录接口的方法定义,前端在请求体中放入 JSON 格式的请求参数,后端则使用 @RequestBody 注解进行接收,并将这些参数转换为对应的实体类。

    为了传参形式的统一,对于 POSTPUT 类型的请求参数,前端传过来的格式要求为 JSONContent-Type 统一设置为 application/json

  4. 复杂对象接收

    当然,有时也会出现复杂对象传参的情况。比如,一个传参对象中包含另一个实体对象,或者多个对象。这种也与对象参数接收的方式一样,前端开发人员需要进行简单的格式转换,在 JSON 串中加一层对象。后端在接收参数时,需要在原有多个对象的基础上再封装一个对象参数。

    笔者以订单生成接口的传参来介绍,该方法的源码定义在 ltd.order.cloud.newbee.controller.NewBeeMallOrderController 类中,代码如下:

    @PostMapping("/saveOrder")
    @ApiOperation(value = "生成订单接口", notes = "传参为地址 id 和待结算的购物项 id 数组")
    public Result<String> saveOrder(@ApiParam(value = "订单参数") @RequestBody
    SaveOrderParam saveOrderParam, @TokenToMallUser MallUserToken loginMallUserToken) {
        // 省略部分代码
    }

    后端需要重新定义一个参数对象,并使用 @RequestBody 注解进行接收和对象转换,SaveOrderParam 类的定义如下:

    public class SaveOrderParam implements Serializable {
    
        @ApiModelProperty("订单项 id 数组")
        private Long[] cartItemIds;
    
        @ApiModelProperty("地址 id")
        private Long addressId;
    }

    前端需要将用户所勾选的购物项id数组和收货地址的 id 传过来,这个接口的传输参数如下:

    {
      "addressId": 0,
      "cartItemIds": [
        1,
        2,
        3
      ]
    }

    关于接口参数的处理,前端开发人员按照后端开发人员给出的接口文档进行参数的封装即可,后端开发人员则需要根据接口的实际情况进行灵活的设计,同时注意 @RequestParam@PathVariable@RequestBody 三个注解的使用。希望读者可以根据本书的内容及项目源码进行举一反三,灵活地设计和开发适合自己项目的接口。

    统一结果响应的设计和使用可以参考 8.3.4 节的内容,这里不再赘述。

    传参的规范和返回结果的统一,都会使控制层、业务层处理的数据格式统一化,保证接口和编码规范的统一性。这种做法对于开发人员在今后的企业级项目开发有着非常重大的意义,规范的参数定义和结果响应能够大大地降低开发成本及沟通成本。