SpringBoot使用接口架构风格RESTful

SpringBoot使用接口架构风格RESTful

概述

RESTful 是非常流行的架构设计风格。首先介绍 REST 的特征、HTTP方法与CRUD动作映射;然后讲解如何基于Spring Boot 设计统一的 RESTful 风格的数据接口;最后讲解在 Spring Boot 下如何使用 RestTemplate 访问 RESTful 接口。

REST – 前后台间的通信方式

什么是 REST

  • REST(Representational State Transfer)表述性状态转换,REST指的是一组架构约束条件和原则
  • 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful 架构
  • REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力,更好地使用现有Web标准中的一些准则和约束

REST 是软件架构的规范体系结构,它将资源的状态以适合客户端的形式从服务器端发送到客户端(或相反方向)。在 REST 中,通过 URL 进行资源定位,用 HTTP 动作(GET、POST、DELETE、PUT等)描述操作,完成功能。

遵循 RESTful 风格,可以使开发的接口通用,以便调用者理解接口的作用。基于 REST 构建的 API 就是 RESTful(REST风格)API 。

各大机构提供的 API 基本都是 RESTful 风格的。这样可以统一规范,减少沟通、学习和开发的成本。


REST 的特征

  • 客户-服务器(client-server):提供服务的服务器和使用服务的客户端需要被隔离对待。
  • 无状态(stateless):服务器端不存储客户请求中的信息,客户的每一个请求必须包含服务器处理请求所需的所有信息,所有的资源都可以通过 URI 定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而变化。
  • 可缓存(cachable):服务器必须让客户知道请求是否可以被缓存。
  • 分层系统(layered System):服务器和客户之间的通信必须被标准化。
  • 统一接口(uniform interface):客户和服务器之间通信的方法必须统一,RESTful 风格的数据元操作 CRUD(create、read、update、delete)分别对应 HTTP 方法–GET用来获取资源,POST用来新建资源、PUT用来更新资源,DELETE用来删除资源,这样就统一了数据操作的接口。
  • HTTP 状态码:状态码在 REST 中都有特定的意义:200、201、202、204、400、401、403、500。如:401 表示用户身份认证失败;403 表示验证身份通过了,但资源没有权限进行操作。
  • 支持按需代码(Code-On-Demand,可选):服务器可以提供一些代码或脚本,并在客户的运行环境中执行。

HTTP 连接最显著的特点是:客户端发送的每次请求都需要服务器回送响应;在请求结束后,主动释放连接。从建立连接到关闭连接的过程称为“一次连接”,前后的请求没有必然的联系,所以是无状态的。


认识 HTTP 方法与 CRUD 动作映射

RESTful 风格使用同一个 URL ,通过约定不同的 HTTP 方法来实施不同的业务

普通的URL 和 RESTful 风格 URL:

  • 查询:
    • 普通URL: article/id=1 ,HTTP 方法:GET
    • RESTfull : article/{id} ,HTTP 方法:GET
  • 添加:
    • 普通URL: article?title=xx&body=xxx ,HTTP 方法:GET/POST
    • RESTfull : article ,HTTP方法:POST
  • 修改:
    • 普通URL: article/update?id=xx&body=xxx ,HTTP 方法:GET/POST
    • RESTfull :article/{id},HTTP方法:PUT 或 PATCH
  • 删除:
    • 普通URL: article/delete?id=xx ,HTTP 方法:GET
    • RESTfull :article/{id},HTTP 方法:DELETE

RESTful 方法的 CRUD 它通过 HTTP 方法来区分增加、修改、删除和查询。

Request

  • GET:查询
GET /zoos
GET /zoos/1
GET /zoos/1/employees
  • POST:创建单个资源。POST一般向“资源集合”型uri发起。
POST /animals  //新增动物
POST /zoos/1/employees //为id为1的动物园雇佣员工
  • PUT:更新单个资源(全量),客户端提供完整的更新后的资源。
  • PATCH 负责部分更新,客户端提供要更新的那些字段。PUT/PATCH一般向“单个资源”型uri发起
PUT /animals/1
PUT /zoos/1
  • DELETE:删除
DELETE /zoos/1/employees/2
DELETE /zoos/1/employees/2;4;5
DELETE /zoos/1/animals //删除id为1的动物园内的所有动物

实现 RESTful 风格的数据增加、删除、修改和查询

在 Spring Boot 中,如果返回 JSON 数据,则只需要在控制器中用 @RestController 注解。使用注解 @RequestMapping 的 value 指定 URI、method 来指定 HTTP方法。

// 获取资源列表
@RequestMapping(value="/article",method=RequestMethod.GET)
public List<Article> list(){
    ...
}

// 根据ID获取资源
@RequestMapping(value="/article/{id}",method=RequestMethod.GET)
public Article findById(@PathVariable("id")Integer id){
    ...
}

// 增加资源
@RequestMapping(value="/article",method=RequestMethod.POST)
public String save(Article article){
    ...
}

// 修改资源
@RequestMapping(value="/article",method=RequestMethod.PUT)
public String update(Article article){
    ...
}

// 根据ID删除资源
@RequestMapping(value="/article/{id}",method=RequestMethod.DELETE)
public String deleteById(@PathVariable("id")Integer id){
    ...
}

设计统一的 RESTful 风格的数据接口

版本控制

随着业务需求的变更、功能的迭代,API的更改是不可避免的。当一个API修改时,就会出现很多问题,比如,可能会在 API 中新增参数、修改返回的数据类型。这就要考虑根据原先版本API编写的客户端如何保留或顺利过渡。所以,需要进行版本控制。

REST 不提供版本控制指南,常用的方法有 3 种:

  • 1.通过URL :通过 URL 是最直接的方法,尽管它违背了 URI 应该引用唯一资源的原则。当版本更新时,还可以保障客户端不会受到影响。
    • 二级目录的方式:
      • API 版本 v1 : http://xxx/api/v1
      • API 版本 v2 : http://xxx/api/v2
    • 二级域名的方式:
      • API 版本 v1 : http://v1.xxx/api
      • API 版本 v2 : http://v2.xxx/api
    • 还可以包括日期、项目名称或其他标识符。
  • 2.通过自定义请求头:自定义头(例: accept-version)允许在版本之间保留 URL 。
  • 3.通过 Accept 标头:客户端在请求资源之前,必须要指定特定头,然后 API 接口负责确定要发送哪个版本的资源。

过滤信息

如果记录数量很多,则服务器不可能一次都将它们返回给用户。API应该提供参数,实现分页返回结果。常用的参数:

  • limit=10 : 指定返回记录的数量。
  • ?page=5&size=10 :指定第几页,以及每页的记录数。
  • ?search_type=1 :指定筛选条件。

确定 HTTP 的方法

在 RESTful 中,HTTP 的方法有以下几种:

  • GET :代表请求资源
  • POST :代表添加资源
  • PUT :代表修改资源。 PUT 是进行全部的修改。如果只修改一个或几个字段,则可以使用 PATCH 方法。
  • DELETE :代表删除资源。
  • HEAD :代表发送 HTTP 头消息, GET 中其实也带了 HTTP 头消息。
  • PATCH :PUT 用于替换资源,而 PATCH 用于更新部分资源。
  • OPTIONS :用于获取 URI 所支持的方法。返回的响应消息会在 HTTP 头中包含 “Allow” 的信息,其值是所支持的方法,如 GET 。

确定 HTTP 的返回状态

HTTP 的返回状态一般有以下几种:

  • 200 :成功
  • 400 :错误请求
  • 404 :没找到资源
  • 403 :禁止
  • 406 :不能使用请求内容特性来响应请求资源,比如请求的是 HTML 文件,但是消费者的 HTTP 头包含了 JSON 要求。
  • 500 :服务器内部错误。

错误处理

  • 不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;
  • 正确设置http状态码,不要自定义;
  • Response body 提供 1)错误的代码(日志/问题追查);2)错误的描述文本(展示给用户)。
  • Java 服务器端一般用异常表示 RESTful API 的错误。
  • API 可能抛出两类异常:业务异常和非业务异常。
    • 业务异常由自己的业务代码抛出,表示一个用例的前置条件不满足、业务规则冲突等,比如参数校验不通过、权限校验失败。
    • 非业务类异常表示不在预期内的问题,通常由类库、框架抛出,或由于自己的代码逻辑错误导致,比如数据库连接失败、空指针异常、除0错误等等。
  • 业务类异常必须提供2种信息:
    • 如果抛出该类异常,HTTP响应状态码应该设成什么;
    • 异常的文本描述;
  • 在Controller层使用统一的异常拦截器:
    • 设置 HTTP响应状态码:对业务类异常,用它指定的 HTTP code;对非业务类异常,统一500;
    • Response Body 的错误码:异常类名
    • Response Body 的错误描述:对业务类异常,用它指定的错误文本;对非业务类异常,线上可以统一文案如“服务器端错误,请稍后再试”,开发或测试环境中用异常的 stacktrace,服务器端提供该行为的开关。

定义统一返回格式

为了保障前后端的数据交互的顺畅,建议规范数据的返回,并采用固定的数据格式封装。

例:

// 异常信息:
{
    "code":10001,
    "msg":"异常信息",
    "data":null
}

// 成功信息:
{
    "code":200,
    "msg":"成功",
    "data":{
        "id":1,
        "name":"xxx"
    }
}

异步任务

  • 对耗时的异步任务,服务器端接受客户端传递的参数后,应返回创建成功的任务资源,其中包含了任务的执行状态。客户端可以轮询该任务获得最新的执行进度。
提交任务:
POST /batch-publish-msg
[{"from":0,"to":1,"text":"abc"},{},{}...]
 
返回:
{"taskId":3,"createBy":"Anonymous","status":"running"}
 
GET /task/3
{"taskId":3,"createBy":"Anonymous","status":"success"}
  • 如果任务的执行状态包括较多信息,可以把“执行状态”抽象成组合资源,客户端查询该状态资源了解任务的执行情况。
提交任务:
POST /batch-publish-msg
[{"from":0,"to":1,"text":"abc"},{},{}...]
 
返回:
{"taskId":3,"createBy":"Anonymous"}
 
GET /task/3/status
{"progress":"50%","total":18,"success":8,"fail":1}

用 RestTemplate 发起请求

认识 RestTemplate

在 Java 应用程序中访问 RESTful 服务,可以使用 Apache 的 HttpClient 来实现。不过此方法使用起来太烦琐。

Spring 提供了一种更简单便捷的模板类-- RestTemplate 来进行操作。

RestTemplate 是 Spring 提供的用于访问 REST 服务的客户端,它提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。

RestTemplate 用于同步 Client 端的核心类,简化与 HTTP 服务的通信。在默认情况下,RestTemplate 默认依赖 JDK 的 HTTP 连接工具。也可以通过 setRequestFactory 属性切换到不同的 HTTP 源,比如 Apache HttpComponents、Netty和 OkHttp 。

RestTemplate 简化了提交表单数据的难度,并附带自动转换为 JSON 格式数据的功能。

RestTemplate 方法:

  • delete , HTTP 方法 DELETE
  • getForObject ,HTTP 方法 GET
  • getForEntity ,HTTP 方法 GET
  • headForHeaders ,HTTP 方法 HEAD
  • optionsForAllow ,HTTP 方法 OPTIONS
  • postForLocation ,HTTP 方法 POST
  • postForObject , HTTP方法 POST
  • put ,HTTP 方法 PUT
  • exchange ,HTTP 方法 any
  • execute , HTTP 方法 any

RestTemplate 默认使用 HttpMessageConverter 将 HTTP 消息转换成 POJO ,或从 POJO 转换成 HTTP 消息,默认情况下会注册主 MIME 类型的转换器,但也可以通过 setMessageConverters 注册其他类型的转换器。

总结

REST(Representational State Transfer)表述性状态转换,REST指的是一组架构约束条件和原则

如果一个架构符合REST的约束条件和原则,我们就称它为RESTful 架构

REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力,更好地使用现有Web标准中的一些准则和约束

REST 是软件架构的规范体系结构,它将资源的状态以适合客户端的形式从服务器端发送到客户端(或相反方向)。在 REST 中,通过 URL 进行资源定位,用 HTTP 动作(GET、POST、DELETE、PUT等)描述操作,完成功能。

遵循 RESTful 风格,可以使开发的接口通用,以便调用者理解接口的作用。这样可以统一规范,减少沟通、学习和开发的成本。

REST 的特征

  • 客户-服务器(client-server)
  • 无状态(stateless)
  • 可缓存(cachable)
  • 分层系统(layered System)
  • 统一接口(uniform interface)
  • 支持按需代码(Code-On-Demand,可选)

RESTful 风格使用同一个 URL ,通过约定不同的 HTTP 方法来实施不同的业务

在 RESTful 中,HTTP 的方法有以下几种:

  • GET :代表请求资源
  • POST :代表添加资源
  • PUT :代表修改资源。 PUT 是进行全部的修改。
  • DELETE :代表删除资源。
  • HEAD :代表发送 HTTP 头消息。
  • PATCH :PUT 用于替换资源,而 PATCH 用于更新部分资源。
  • OPTIONS :用于获取 URI 所支持的方法。

设计统一的 RESTful 风格的数据接口

版本控制

  • 随着业务需求的变更、功能的迭代,API的更改是不可避免的。这就要考虑根据原先版本API编写的客户端如何保留或顺利过渡。所以,需要进行版本控制。
  • REST 不提供版本控制指南,常用的方法有 3 种:
    • 1.通过URL
    • 2.通过自定义请求头
    • 3.通过 Accept 标头

过滤信息

  • 如果记录数量很多,则服务器不可能一次都将它们返回给用户。API应该提供参数,实现分页返回结果。

确定 HTTP 的方法

确定 HTTP 的返回状态

错误处理

  • 不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;
  • 正确设置http状态码,不要自定义;
  • Response body 提供 1)错误的代码(日志/问题追查);2)错误的描述文本(展示给用户)。
  • Java 服务器端一般用异常表示 RESTful API 的错误。
  • API 可能抛出两类异常:业务异常和非业务异常。
  • 在Controller层使用统一的异常拦截器

定义统一返回格式

  • 为了保障前后端的数据交互的顺畅,建议规范数据的返回,并采用固定的数据格式封装。

异步任务

  • 对耗时的异步任务,服务器端接受客户端传递的参数后,应返回创建成功的任务资源,其中包含了任务的执行状态。客户端可以轮询该任务获得最新的执行进度。
  • 如果任务的执行状态包括较多信息,可以把“执行状态”抽象成组合资源,客户端查询该状态资源了解任务的执行情况。

认识 RestTemplate

RestTemplate 是 Spring 提供的用于访问 REST 服务的客户端,它提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。

公众号

知行chen

参考

《Spring Boot 实战派》 龙中华

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值