概述
有了新的数据源 连接并准备调用,我们可以在数据获取器方法中连接一些点。
在本课中,我们将
- 将我们的数据获取器连接到我们的 数据源
- 考虑 REST API 响应中不熟悉 JSON 属性
- 将 JSON 对象映射到我们可以操作和推断的 Java 类
使用数据源
现在我们有一个方便的方法可以调用 REST API 获取精选列表数据。所以... 运行我们的FeaturedListings
查询 会返回真实数据吗?
query FeaturedListings {featuredListings {idtitlenumOfBedscostPerNightclosedForBookings}}
不完全是!当此 查询 被执行时,DGS 首先要做的是查找相应的数据获取器方法 featuredListings
。在这种情况下,就是 ListingDataFetcher
中的 featuredListings
方法。
当然,这个方法 仍然 只是返回硬编码数据。它无法调用我们的 ListingService.featuredListingsRequest
方法,因为它还没有了解它。
让我们回到 datafetchers/ListingDataFetcher
中来修复它。
在数据获取器中使用 ListingService
首先,我们将导入 ListingService
,并给我们的类一个 listingService
属性。然后,我们将包含一个在类上连接一切的构造函数。(我们还将包含 IOException
以便很快处理任何抛出的异常!)
// ...other importsimport com.example.listings.datasources.ListingService;import org.springframework.beans.factory.annotation.Autowired;import java.io.IOException;@DgsComponentpublic class ListingDataFetcher {private final ListingService listingService;@Autowiredpublic ListingDataFetcher(ListingService listingService) {this.listingService = listingService;}// featuredListings method}
请注意,我们使用 Spring @Autowired
注释来利用依赖注入。这意味着当我们创建 ListingDataFetcher
类的一个实例时,将自动注入 ListingService
的实例。
在我们的类的 featuredListings
数据获取器方法中(DGS 将为此方法调用 Query.featuredListings
字段!)中,我们将首先清理我们的模拟。
@DgsQuerypublic 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
方法,并返回结果。
@DgsQuerypublic 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 {idtitlenumOfBedscostPerNightclosedForBookings}}
糟糕!又一个错误!
这是我们终端中的消息
Unrecognized field "description" (class com.example.listings.models.ListingModel),not marked as ignorable (5 known properties: "title", "id", "numOfBeds", "costPerNight", "closedForBookings"])
我们看到这个错误是因为我们的 ListingModel
类只知道如何处理五个特定属性:id
、title
、numOfBeds
、costPerNight
和 closedForBookings
。
但我们正在尝试将响应中的每个 JSON 对象(包含更多属性)转换为 ListingModel
的实例。当我们检查 REST 端点中的一个列表对象时,我们可以看到 "hostId"
确实是一个属性。但是我们的 ListingModel
类不知道该如何处理它!
JsonIgnoreProperties
注释
Jackson 包提供了一个注释 - JsonIgnoreProperties
- 来处理这种情况。通过在类上设置 @JsonIgnoreProperties
并向它传递一个 参数 ignoreUnknown = true
,我们可以指示我们的类忽略它遇到的任何 不熟悉 的 JSON 属性,并处理它识别的内容。
让我们将这个注释应用到我们的 ListingModel
类来解决错误。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;@JsonIgnoreProperties(ignoreUnknown = true)public class ListingModel {}
有了这个,让我们再次重新启动服务器来查看添加这个注释的效果。
运行查询,获取数据!
回到 浏览器 中,让我们再次尝试那个 查询。
query GetFeaturedListings {featuredListings {idtitlenumOfBedscostPerNightclosedForBookings}}
在 响应 面板中,我们现在应该看到来自 REST API 的实际数据!
关键要点
- 数据获取器方法可以直接连接到我们的 数据源 中的 GraphQL API
- 的
JsonIgnoreProperties
注释允许我们在实例化新类时忽略不熟悉的 JSON 属性
接下来
太棒了!我们已经将 REST API 响应翻译成我们在模式中定义的类型,并且我们拥有无缝的 查询 体验。但现在,我们的列表非常稀疏。根据我们的模型,我们需要开始探索一些额外的功能 - 例如查询其他列表属性(您好,便利设施!)或请求 特定 的列表。让我们在下一课中提升我们的 GraphQL API。
分享您对本课的疑问和评论
本课程目前处于
您需要一个 GitHub 帐户才能在下面发帖。还没有? 改在我们的奥德赛论坛上发帖。