- 😜作 者:是江迪呀
- ✒️本文关键词:
HTTP
、RESTFul
、请求
- ☀️每日 一言:
我已经习惯这样的失望了——《英雄联盟》奥恩
一、前言
为了更好地设计和构建分布式系统和网络应用,诞生了RESTful
风格,它的设计强调了简单性、可伸缩性、可维护性和可组合性,这些特性使其成为构建分布式系统和 Web
服务的常用选择。遵循这些原则可以使 API
更具可读性、可维护性和可伸缩性。
二、RESTFul介绍
2.1 原则和特点
RESTful
是一种架构风格,它是一组约束和原则,用于设计分布式系统和网络应用程序。REST
是 “Representational State Transfer” 的缩写,它强调网络中资源的状态和表现,并采用了一些关键原则:
-
资源 (Resources): 在
REST
中,一切都被视为资源,每个资源都有一个唯一的标识符(通常是一个URL
)。这些资源可以是物理实体,也可以是虚拟概念,如数据、服务、文件等。 -
状态 (State): 客户端通过资源的状态进行操作。资源的状态可以更改,例如,一个订单可以处于已支付或未支付的状态。
-
表现层 (Representation): 资源的状态以某种方式呈现给客户端,通常是以
JSON
或XML
格式。客户端可以通过获取、创建、修改或删除这些资源的表现层来与资源进行交互。 -
统一接口 (Uniform Interface): RESTful 服务应该具有统一的接口,包括一组标准的操作方法,如
GET(获取资源)
、POST(创建资源)
、PUT(更新资源
)、DELETE(删除资源)
等。 -
状态无关性 (Stateless): 每个客户端请求必须包含足够的信息,以便服务器可以理解并处理请求,而不需要保存客户端的状态信息。每个请求都应该是独立的,服务器不会存储客户端的上下文信息。
-
资源之间的链接 (Resource Linking): 在
RESTful
架构中,资源之间可以通过超链接相互关联。这些链接可以帮助客户端导航资源之间的关系。 -
无状态通信 (Stateless Communication):
RESTful
通信是无状态的,每个请求都应该包含足够的信息,以便服务器可以理解并处理请求,而不需要存储客户端的状态信息。
2.2 优势
-
简化通信:
RESTful
风格基于HTTP
协议,使用标准的HTTP
方法和状态码,使通信更加简单和直观。这降低了开发者的学习成本,使他们能够更容易地理解和使用 API。 -
统一接口: RESTful 风格倡导使用统一的接口原则,无论资源是什么,都使用相同的 HTTP 动词(
GET
、POST
、PUT
、DELETE
等)来执行操作。这种一致性使得 API 更易于设计和维护。 -
松散耦合:
RESTful
架构鼓励松散耦合的设计,客户端和服务器之间的关系更加独立。这使得系统更容易扩展和维护,允许独立地修改客户端或服务器的一部分而不影响整体系统。 -
可伸缩性:
RESTful
架构天生支持分布式系统,它的无状态性和资源导向性使得系统更容易扩展,可以适应不断增长的用户和数据量。 -
可见性:
RESTful
的资源URL
是自解释的,它们通常包含了有关资源的信息。这使得开发者和系统管理员可以更容易地理解和监控系统。 -
性能:
RESTful
风格的通信基于HTTP
,这是一个广泛部署和优化的协议。因此,RESTful
风格的API
在性能方面通常表现出色。
2.3 如何使用
规范的使用RESTFul
风格,首先要知道一个概念:以资源驱动的方式。以资源驱动的方式书写接口的URL
是一种 RESTful
风格的设计方法,它将网络应用程序的功能映射到资源的操作上,强调使用标准的 HTTP
方法(GET
、POST
、PUT
、DELETE
等)来执行操作。
主要体现在两个方面:HTTP请求方式 和 URL命名
(1)URL命名:
在 RESTful 风格中,资源通常用名词来表示,而不是动词。例如,一个博客系统可以有文章资源,而不是 getArticle()
或 fetchArticle()
方法。
示例:/articles
表示所有文章资源,/articles/1
表示ID
为 1
的文章。
(2)HTTP请求方式:
标准的 HTTP 方法(GET
、POST
、PUT
、DELETE
等)用于表示对资源的操作。例如,
- 使用
GET
方法来获取资源; - 使用
POST
方法来创建新资源; - 使用
PUT
方法来更新资源; - 使用
DELETE
方法来删除资源。
示例: 获取文章列表使用 GET
,创建新文章使用 POST
,更新文章使用 PUT
,删除文章使用 DELETE
。
三、实际应用
@RestController
@RequestMapping("/api/users")
public class UserController {
private final List<User> userList = new ArrayList<>(); // 用于存放用户的列表
// 获取所有用户列表
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
return ResponseEntity.ok(userList);
}
// 获取单个用户信息
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = findUserById(id);
if (user != null) {
return ResponseEntity.ok(user);
} else {
return ResponseEntity.notFound().build();
}
}
// 创建新用户
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
userList.add(user);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
// 更新用户信息
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
User user = findUserById(id);
if (user != null) {
user.setUsername(updatedUser.getUsername());
user.setEmail(updatedUser.getEmail());
return ResponseEntity.ok(user);
} else {
return ResponseEntity.notFound().build();
}
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
User user = findUserById(id);
if (user != null) {
userList.remove(user);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}