读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用Spring Boot创建REST风格的Web服务
在本章中,我们将首先使用控制器类创建一个 RESTful Web 服务。之后,我们将演示如何使用 Spring Data REST 创建一个 RESTful Web 服务,该服务还自动涵盖所有 CRUD 功能。 我们使用在上一章中创建的数据库应用程序作为起点。
在本章中,我们将研究以下内容:
- What the RESTful web service is
- How to create a RESTful web service with Spring Boot
- How to test the RESTful web service
Web 服务是使用 HTTP 协议通过 Internet 进行通信的应用程序。有许多不同类型的 Web 服务架构,但所有设计的主要思想都是相同的。在本书中,我们将根据当今非常流行的设计创建一个 RESTful Web 服务。
REST(具象状态转移)是一种架构 style 用于创建网络服务。 REST 不是标准的,但它定义了由 Roy Fielding 定义的set 约束。六个约束如下:
- Stateless: The server doesn't hold any information about the client state.
- Client server: The client and server act independently. The server does not send any information without a request from the client.
- Cacheable: Many clients often request the same resources, therefore it is useful to cache responses in order to improve performance.
- Uniform interface: Requests from different clients look the same. Clients may be, for example, a browser, a Java application, and a mobile application.
- Layered system: REST allows us to use a layered system architecture.
- Code on demand: This is an optional constraint.
统一接口是一个重要的约束,它定义了每个 REST 架构都应该具有以下元素:
- Identification of resources: There are resources with their unique identifiers, for example, URIs in web-based REST services. REST resources should expose easily understood directory structure URIs. Therefore, a good resource naming strategy is very important.
- Resource manipulation through representation: When making a request to a resource, the server responds with a representation of the resource. Typically, the format of the representation is JSON or XML.
- Self descriptive messages: Messages should have enough information that the server knows how to process them.
- Hypermedia and the Engine of Application State (HATEOAS): Responses can contain links to other areas of service.
我们将在以下主题中开发的 RESTful Web 服务遵循 REST 架构原则。
在 Spring Boot 中,所有 HTTP 请求都由控制器类处理。为了能够创建 RESTful Web 服务,首先,我们必须创建一个控制器类。我们将为控制器创建自己的 Java 包:
- Activate the root package in the Eclipse
Project Explorer
and right-click. SelectNew
|Package
from the menu. We will name our new packagecom.packt.cardatabase.web
:
- Next, we will create a new controller class in a new web package. Activate the
com.packt.cardatabase.web
package in the Eclipse project explorer and right-click. SelectNew
|Class
from the menu. We will name our classCarController
:
Note
如果您不小心在错误的包中创建了类,您可以在 Eclipse Project Explorer
中的包之间拖放文件。有时,当您进行一些更改时,Eclipse Project Explorer
视图可能无法正确呈现。刷新项目浏览器有帮助(激活 Project Explorer
并按 F5 )。
- Open your controller class in the editor window and add the
@RestController
annotation before the class definition. See the following source code. The@RestController
annotation identifies that this class will be the controller for the RESTful web service:
- Next, we add a new method inside our controller class. The method is annotated with the
@RequestMapping
annotation, which defines the endpoint that the method is mapped to. Following, you can see the sample source code. In this example, when a user navigates to the/cars
endpoint, thegetCars()
method is executed:
getCars()
方法返回所有汽车对象,然后由 Jackson 库编组为 JSON 对象。
Note
默认情况下,@RequestMapping
处理所有 HTTP 方法(GET
、PUT
、
POST
等)请求。您可以使用以下 @RequestMapping("/cars", method=GET)
参数定义接受哪种方法。 现在,此方法仅处理来自 /cars
端点的 GET
请求。
- Now, we are ready to run our application and navigate to
localhost:8080/cars
. We can see that there is something wrong, and the application seems to be in an infinite loop. That happens due to our one-to-many relationship between the car and owner tables. So, what happens in practice—first, the car is serialized, and it contains an owner that is then serialized, and that, in turn, contains cars that are then serialized... and so on. To avoid this, we have to add the@JsonIgnore
annotation to thecars
field in theOwner
class:
我们已经完成了我们的第一个 RESTful Web 服务,它返回所有的汽车。 Spring Boot 提供了一种更强大的方式来创建 RESTful Web 服务,这将在下一个主题中进行研究。
Spring Data REST 是 Spring Data 项目的一部分。它提供了一种简单 和快速的方式来使用Spring 实现RESTful Web 服务。首先,使用 Spring Data REST,您必须将以下依赖项添加到 pom.xml
文件中:
默认情况下,Spring Data REST 从应用程序中查找所有公共存储库,并为您的实体自动创建 RESTful Web 服务。
您可以在 application.properties
文件中定义服务端点:
现在您可以从 localhost:8080/api
端点访问 RESTful Web 服务。通过调用服务的根端点,它返回可用的资源。 Spring Data REST 在 HAL(超文本应用程序语言
)格式。 HAL 格式 提供 一组用于在 JSON 中表达超链接的约定,它使您的 RESTful Web 服务更易于前端开发人员使用:
我们可以看到有汽车和车主实体服务的链接。 Spring Data Rest 服务路径名派生自实体名称。然后该名称将是复数形式且不大写。例如,实体 Car 服务路径名将命名为 cars
。配置文件链接由 Spring Data Rest 生成,它包含特定于应用程序的元数据。
现在,我们开始更仔细地检查不同的服务。有多种工具可用于测试和使用 RESTful Web 服务。在本书中,我们使用 Postman,但您可以使用您熟悉的工具,例如 cURL。 Postman 可以作为桌面应用程序 或浏览器插件获取。通过使用 Windows Ubuntu Bash,cURL 也可用于 Windows 10。
如果你使用 cars
端点http://localhost:8080/api/cars
发出请求class="literal">GET 方法,您将获得所有 汽车
的列表,如下图所示:
在 JSON 响应中,您可以看到有一个 cars
数组,每辆汽车都包含汽车特定的数据。所有的汽车还有 "_links"
属性,它是一个链接的集合,通过这些你可以访问汽车本身或获取汽车的所有者。要访问一辆特定的汽车,路径将是 http://localhost:8080/api/cars/{id}
。
对 http://localhost:8080/api/cars/3/owner
的请求返回汽车的所有者。响应现在包含车主数据、车主链接以及用户拥有的其他 汽车
的链接:
Spring Data Rest 服务提供所有 CRUD 操作。下表显示了可用于不同 CRUD 操作的 HTTP 方法:
HTTP 方法 |
CRUD |
|
|
|
|
|
|
|
|
接下来,我们将了解如何使用我们的 RESTful Web 服务从 database 中删除汽车。在删除操作中,您必须使用 DELETE
方法和要删除的汽车的链接(http://localhost: 8080/api/cars/{id}
)。以下截图显示了如何使用 cURL 删除 ID 为4
的一辆汽车。 在删除请求之后,您可以看到现在剩下两辆汽车在数据库:
当我们要向数据库中添加一辆新车时,我们必须使用 POST
方法,链接为http://localhost :8080/api/cars
.标头必须包含 Content-Type
字段,其值为 Content-Type:application/json
,新的汽车对象将嵌入到请求正文中:
响应将发回一个新创建的汽车对象。现在,如果您再次向 http://localhost:8080/api/cars
路径发出 GET
请求,可以看到数据库中存在新车:
要更新实体,我们必须使用 PATCH
方法和我们要更新的汽车的链接 (http://localhost:8080/api/cars/{id}
)。 标头必须包含 内容-Type
字段的值为Content-Type:application/json
以及带有编辑数据的汽车对象将在请求中给出身体。如果您使用 PATCH
,您必须只发送更新的字段。如果您使用 PUT
,则必须包含所有要请求的字段。让我们编辑我们在上一个示例中创建的汽车。我们将更改颜色为白色并填写我们留空的寄存器号。
我们还将使用所有者字段将所有者链接到汽车。所有者字段的内容是所有者的链接 (http://localhost:8080/api/owners/{id}
)。以下屏幕截图显示了 PATCH
请求内容:
使用 GET
请求获取所有汽车后,您可以看到汽车已更新:
在上一章中,我们创建了对存储库的查询。这些查询也可以包含在我们的服务中。要包含查询,您必须将 @RepositoryRestResource
注释添加到存储库类。查询参数使用 @Param
注释进行注释。以下源代码显示了我们的 CarRepository
带有这些注释:
现在,当您向 http://localhost:8080/api/cars
路径发出 GET
请求时,您可以看到有一个名为 /search
的新端点。调用 http://localhost:8080/api/cars/search
路径返回以下响应:
从响应中,您可以看到这两个查询现在在我们的服务中可用。以下 URL 演示了如何按品牌获取汽车:
- What is REST?
- How can you create a RESTful web service with Spring Boot?
- How can you fetch items using our RESTful web service?
- How can you delete items using our RESTful web service?
- How can you add items using our RESTful web service?
- How can you update items using our RESTful web service?
- How can you use queries with our RESTful web service?
Pack 有其他很好的资源用于学习 Spring Boot RESTful Web 服务: