8. 使用数据源
10m

概述

有了新的 连接并准备调用,我们可以在数据获取器方法中连接一些点。

在本课中,我们将

  • 将我们的数据获取器连接到我们的
  • 考虑 REST API 响应中不熟悉 JSON 属性
  • 将 JSON 对象映射到我们可以操作和推断的 Java 类

使用数据源

现在我们有一个方便的方法可以调用 REST API 获取精选列表数据。所以... 运行我们的FeaturedListings 会返回真实数据吗?

query FeaturedListings {
featuredListings {
id
title
numOfBeds
costPerNight
closedForBookings
}
}

不完全是!当此 被执行时,DGS 首先要做的是查找相应的数据获取器方法 featuredListings。在这种情况下,就是 ListingDataFetcher 中的 featuredListings 方法。

当然,这个方法 仍然 只是返回硬编码数据。它无法调用我们的 ListingService.featuredListingsRequest 方法,因为它还没有了解它。

让我们回到 datafetchers/ListingDataFetcher 中来修复它。

在数据获取器中使用 ListingService

首先,我们将导入 ListingService,并给我们的类一个 listingService 属性。然后,我们将包含一个在类上连接一切的构造函数。(我们还将包含 IOException 以便很快处理任何抛出的异常!)

ListingDataFetcher
// ...other imports
import com.example.listings.datasources.ListingService;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
@DgsComponent
public class ListingDataFetcher {
private final ListingService listingService;
@Autowired
public ListingDataFetcher(ListingService listingService) {
this.listingService = listingService;
}
// featuredListings method
}

请注意,我们使用 Spring @Autowired 注释来利用依赖注入。这意味着当我们创建 ListingDataFetcher 类的一个实例时,将自动注入 ListingService 的实例。

在我们的类的 featuredListings 数据获取器方法中(DGS 将为此方法调用 Query.featuredListings !)中,我们将首先清理我们的模拟。

@DgsQuery
public List<ListingModel> featuredListings() {
- ListingModel meteorListing = new ListingModel();
- meteorListing.setId("1");
- meteorListing.setTitle("Beach house on the edge of the Laertes meteor");
- meteorListing.setCostPerNight(360.00);
- meteorListing.setClosedForBookings(false);
- meteorListing.setNumOfBeds(3);
-
- ListingModel gasGiantListing = new ListingModel();
- gasGiantListing.setId("2");
- gasGiantListing.setTitle("Unforgettable atmosphere, unbeatable heat, tasteful furnishings");
- gasGiantListing.setCostPerNight(124.00);
- gasGiantListing.setClosedForBookings(true);
- gasGiantListings.setNumOfBeds(4);
-
- return List.of(meteorListing, gasGiantListing);
}

接下来,我们将调用我们类的 listingService 实例上的 featuredListingsRequest 方法,并返回结果。

@DgsQuery
public List<ListingModel> featuredListings() {
return listingService.featuredListingsRequest();
}

最后,由于 featuredListingsRequest 会抛出异常,让我们也更新 featuredListings 数据获取器的方法签名。

public List<ListingModel> featuredListings() throws IOException {
// ...method body
}

是时候回到浏览器了!首先,让我们确保重新启动服务器,以便运行最新的更改。

任务!

现在让我们导航回浏览器 并检查与 https://127.0.0.1:8080/graphql 的连接是否仍然有效。

让我们对我们的 做一个小的调整,然后再运行它;让我们将名称从 FeaturedListings 更改为 GetFeaturedListings。(它更能描述我们对精选列表的 确切 操作!)

然后,鼓声响起...

query GetFeaturedListings {
featuredListings {
id
title
numOfBeds
costPerNight
closedForBookings
}
}

糟糕!又一个错误!

https://studio.apollographql.com/sandbox/explorer

A screenshot of the Explorer, with an error in the response panel

这是我们终端中的消息

Unrecognized field "description" (class com.example.listings.models.ListingModel),
not marked as ignorable (5 known properties: "title", "id", "numOfBeds", "costPerNight", "closedForBookings"])

我们看到这个错误是因为我们的 ListingModel 类只知道如何处理五个特定属性:idtitlenumOfBedscostPerNightclosedForBookings

但我们正在尝试将响应中的每个 JSON 对象(包含更多属性)转换为 ListingModel 的实例。当我们检查 REST 端点中的一个列表对象时,我们可以看到 "hostId" 确实是一个属性。但是我们的 ListingModel 类不知道该如何处理它!

JsonIgnoreProperties 注释

Jackson 包提供了一个注释 - JsonIgnoreProperties - 来处理这种情况。通过在类上设置 @JsonIgnoreProperties 并向它传递一个 ignoreUnknown = true,我们可以指示我们的类忽略它遇到的任何 不熟悉 的 JSON 属性,并处理它识别的内容。

让我们将这个注释应用到我们的 ListingModel 类来解决错误。

models/ListingModel
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ListingModel {
}

有了这个,让我们再次重新启动服务器来查看添加这个注释的效果。

任务!

运行查询,获取数据!

回到 浏览器 中,让我们再次尝试那个

query GetFeaturedListings {
featuredListings {
id
title
numOfBeds
costPerNight
closedForBookings
}
}

响应 面板中,我们现在应该看到来自 REST API 的实际数据!

https://studio.apollographql.com/sandbox/explorer

A screenshot of the Explorer, showing a successful response to our query

关键要点

  • 数据获取器方法可以直接连接到我们的 中的 API
  • JsonIgnoreProperties 注释允许我们在实例化新类时忽略不熟悉的 JSON 属性

接下来

太棒了!我们已经将 REST API 响应翻译成我们在模式中定义的类型,并且我们拥有无缝的 体验。但现在,我们的列表非常稀疏。根据我们的模型,我们需要开始探索一些额外的功能 - 例如查询其他列表属性(您好,便利设施!)或请求 特定 的列表。让我们在下一课中提升我们的 API。

上一页

分享您对本课的疑问和评论

本课程目前处于

测试版
.您的反馈可以帮助我们改进!如果您遇到困难或感到困惑,请告诉我们,我们会帮助您。所有评论都是公开的,必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被删除。

您需要一个 GitHub 帐户才能在下面发帖。还没有? 改在我们的奥德赛论坛上发帖。