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

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

  1. 普通参数接收

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

    图1-29 订单微服务中添加收货地址接口的测试结果
    @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. 对象参数接收

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

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

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

    为了传参形式的统一,对于 POSTPUT 方法类型的请求参数,前端传过来的格式要求为 JSON 形式,Content-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 节中的内容,这里不再赘述。

    传参的规范和结果响应的统一,都会使控制层、业务层处理的数据格式一致化,保证了接口和编码规范的统一。这种做法不仅体现在本项目中,而且对开发人员在今后的企业级项目开发工作中也有着非常重要的意义,规范的参数定义和结果响应会极大程度地降低开发成本及沟通成本。