Fork me on GitHub

Restful接口规范学习总结

关于Restful

  • REST 全称是REpresentational State Transfer 即表现层状态转移。
  • 觉得这个翻译有点反人类,一般人应该都听不懂……
  • 搜了下,找到一些比较通俗易懂的解释:

    • 描述一:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
    • 描述二:REST 就是 URI 只作为名词,所有操作名词的动作都用HTTP方法来表示;RESTFul的架构就是,URI不能包含动作,所有的都是资源,只有HTTP的方法才能操作。

      • 这里简单说下URI和URL的区别:
        URI = Universal Resource Identifier 统一资源标识符,可以唯一标识一个资源。
        URL = Universal Resource Locator 统一资源定位符,可以提供找到该资源的路径。
        比如我在搜索这个解释时访问的网址:
        https://www.zhihu.com/question/21950864。
        这就是一个URL;而21950864作为一个问题的标识符,可以定位到这个问题,就是URI。
        同时,URL也是URI的子集,因为它也能标识出一个资源。
    • 描述三:REST描述的是在网络中client和server的一种交互形式,Server提供的RESTful API中,URL中只使用名词来指定资源,原则上不使用动词。而用HTTP协议里的动词来实现资源的添加,修改,删除等操作。即通过HTTP动词来实现资源的状态扭转。

    这里不多做说明,详细可参考:怎样用通俗的语言解释REST,以及RESTful

RestFul规范学习总结

HTTP动词规定

一张图说明:

image

推荐写法

  • url小写驼峰命名,名词单数。
  • GET查询数据时,根据id查询和根据条件过滤查询对应两个接口。
  • 全更新PUT,部分更新PATCH。
  • 更新时对象id要在url里单独传递,然后再塞到对象里。且更新后不需要返回前端对象。
  • 创建时用POST方法,且放到http body里(用@RequestBody)传递对象。
  • DELETE时返回受影响行数。
  • 如果对象有层级关系需要同时传入父id。
  • 主键用@PathVariable传递,其他参数用@RequestParam或者@RequestBody。
  • 编码等的重复性校验尽量使用查询接口,查询无数据即校验通过。
  • 主键应该通过URL地址传递,其他参数通过URL参数传递。
    Controller层通过注解的方式来获取参数:

    • @PathVariable 用于获取路径中的内容。
    • @RequestParam 用于获取请求参数的内容,如果Controller层使用对象映射字段的话,也可不加该注解。
    • @RequestBody 用于获取HTTP body里面内容。
  • 添加API注解,如:

    • @Api(description = “接口类Controller描述”)
    • @ApiOperation(value = “接口方法说明”)
    • @ApiParam(required = “是否必须参数”, value = “方法参数具体描述”)
    • @ApiModel(value = “对象描述”)
    • @ApiModelProperty(value = “对象字段描述”)

接口示例

  • 类前注释

    1
    2
    3
    4
    5
    @RestController
    @RequestMapping("/customer/fellowNbrType")
    @Api(description = "类的描述")
    @Service
    public class FellowNbrTypeService {
  • GET

    1
    2
    3
    4
    5
    6
    7
    8
    //通过主键查询:id放在url里传递
    @ApiOperation(value = "根据主键查询亲情号码类型")
    @RequestMapping(value = "/{fellowNbrTypeId}", method = RequestMethod.GET)
    public FellowNbrTypeDto queryFellowNbrType(
    @ApiParam(required = true, value = "fellowNbrTypeId") @PathVariable Long fellowNbrTypeId)
    throws BaseAppException {
    return mapper.selectByPrimaryKey(fellowNbrTypeId);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      //通过过滤条件查询
    @ApiOperation(value = "查询所有亲情号码类型")
    @RequestMapping(method = RequestMethod.GET)
    public List<FellowNbrTypeDto> queryFellowNbrTypeList(FellowNbrTypeDto fellowNbrTypeDto) throws BaseAppException {

    if (fellowNbrTypeDto == null) {
    fellowNbrTypeDto = new FellowNbrTypeDto();
    }
    fellowNbrTypeDto.setSpId(ThreadLocalMap.getSpId());
    return mapper.selectList(fellowNbrTypeDto);
    }
    1
    2
    3
    4
    5
    6
    7
    @ApiOperation(value = "查询亲情号码类型")
    @RequestMapping(value = "/getFellowNbrType", method = RequestMethod.GET)
    public List<FellowNbrTypeDto> queryFellowNbrTypeList(
    @ApiParam(required = true, value = "subsPlanId") @RequestParam Long subsPlanId,
    @ApiParam(required = true, value = "servTypes") @RequestParam String servTypes) throws BaseAppException {
    return fellowNbrTypeManager.queryFellowNbrTypeList(subsPlanId, servTypes);
    }
  • POST

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @RequestMapping(method = RequestMethod.POST)
    @ApiOperation(value = "增加亲情号码类型")
    @Transactional
    public FellowNbrTypeDto addFellowNbrType(
    @ApiParam(required = true, value = "亲情号码类型") @RequestBody FellowNbrTypeDto fellowNbrTypeDto)
    throws BaseAppException {
    fellowNbrTypeManager.addFellowNbrType(fellowNbrTypeDto);
    return fellowNbrTypeDto;
    }
  • PUT

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      //更新时对象id要在url里单独传递
    @ApiOperation(value = "更新亲情号码类型")
    @RequestMapping(value = "/{fellowNbrTypeId}", method = RequestMethod.PUT)
    @Transactional
    public FellowNbrTypeDto modifyFellowNbrTypeWithNull(
    @ApiParam(required = true, value = "fellowNbrTypeId") @PathVariable Long fellowNbrTypeId, @ApiParam(
    required = true, value = "亲情号码类型信息") @RequestBody FellowNbrTypeDto fellowNbrTypeDto)
    throws BaseAppException {
    fellowNbrTypeDto.setFellowNbrTypeId(fellowNbrTypeId);
    fellowNbrTypeManager.modifyFellowNbrType(fellowNbrTypeDto, true);
    return fellowNbrTypeDto;
    }
  • PATCH

    除了Method,其他和PUT相同。

  • DELETE

    1
    2
    3
    4
    5
    6
    7
    8
    @ApiOperation(value = "删除亲情号码类型")
    @RequestMapping(value = "/{fellowNbrTypeId}", method = RequestMethod.DELETE)
    @Transactional
    public int removeFellowNbrType(
    @ApiParam(required = true, value = "fellowNbrTypeId") @PathVariable Long fellowNbrTypeId)
    throws BaseAppException {
    return fellowNbrTypeManager.deleteFellowNbrType(fellowNbrTypeId);
    }