9. 向实体贡献字段
5m

概述

我们终于可以添加recommendedPlaylists 到一个 Recipe!

在本课中,我们将

  • 学习多个 如何贡献 到一个

定义实体

The Recipe 类型已标记为 recipes 中。我们可以通过查看 Studio 中的 Schema 页面并选择 Objects 来确认这一点。

https://studio.apollographql.com

Schema - Objects page

Recipe 类型旁边是 E 标签,表示它是一个 类型。点击该类型,我们可以进一步看到该实体的关键 : id.

这太好了!The recipes 已经为我们打开了向该 贡献 的途径。让我们继续这样做,回到代码编辑器中的项目。

让我们在 Types 文件夹中创建一个名为 Recipe 的新类。

Types/Recipe.cs
namespace Odyssey.MusicMatcher;
public class Recipe
{
}

记住,要定义一个 ,我们需要两样东西:一个主键 ([Key]) 和一个引用 ([ReferenceResolver]).

定义主键

  1. 首先,让我们在文件顶部导入 HotChocolate.ApolloFederation 包。

    Types/Recipe.cs
    using HotChocolate.ApolloFederation;
  2. Recipe 类中,我们将添加 Id 作为类的属性,使用 自动实现属性的简写语法。注意,这里我们使用大写 Id 来遵循 C# 惯例,但在幕后,Hot Chocolate 在生成 时会将其转换为小写。此属性返回 string 类型。

    Types/Recipe.cs
    public string Id { get; }
  3. 我们还将使用 [ID] 属性来注释此属性。尽管 Id 返回 string 类型,但我们希望将其映射到 类型 ID,而不是 String.

    Types/Recipe.cs
    [ID]
    public string Id { get; }
  4. 最后,我们将使用 Key 属性标记该属性,它将其指定为主键。

    Types/Recipe.cs
    [ID]
    [Key]
    public string Id { get; }

定义引用解析器函数

除了主键之外,我们还需要一个引用 :一个返回特定实体实例的函数。

  1. 让我们定义一个新的函数,它将是 public static。我们将将其命名为 GetRecipeById。引用 的名称并不重要,但我们应该对它正在做什么进行描述。此函数将返回 Recipe 类型 (即 类型!)。

    Types/Recipe.cs
    public static Recipe GetRecipeById()
    {
    }
  2. 要将其标记为 的引用 ,我们将使用 [ReferenceResolver] 属性。

    Types/Recipe.cs
    [ReferenceResolver]
    public static Recipe GetRecipeById()
  3. 对于此函数的参数,我们可以访问 的关键 (s)。在本例中,即 id 属性。

    Types/Recipe.cs
    public static Recipe GetRecipeById(
    string id
    )
  4. 在函数主体中,我们将使用 id 返回 Recipe 类的实例来实例化它。

    Types/Recipe.cs
    return new Recipe(id);
  5. 最后,我们将为 Recipe 类编写构造函数,它接受 string id 并将其分配给 Id 属性。

    Types/Recipe.cs
    public Recipe(string id)
    {
    Id = id;
    }

贡献实体

太棒了,我们已经填好了 stub,它定义了新的 中实体的必要条件:定义实体所需的最小值。现在,让我们添加新的 来实现我们的梦想 :食谱的推荐播放列表。

  1. Recipe 类的主体内部,添加一个名为 RecommendedPlaylists 的新 函数。现在,我们将使用硬编码数据。我们将在下一课中将其替换为对我们 的调用。

    The RecommendedPlaylists 方法将返回一个 Playlist 对象列表。

    Types/Recipe.cs
    public List<Playlist> RecommendedPlaylists()
    {
    return new List<Playlist>
    {
    new Playlist("1", "GraphQL Groovin'"),
    new Playlist("2", "Graph Explorer Jams"),
    new Playlist("3", "Interpretive GraphQL Dance")
    };
    }
  2. 让我们也为这个 添加一个描述。

    Types/Recipe.cs
    [GraphQLDescription(
    "A list of recommended playlists for this particular recipe. Returns 1 to 3 playlists."
    )]

注册实体

最后一步:我们需要将这种类型注册到我们的。打开Program.cs,找到我们初始化的那一行。为了将所有类似的方法调用分组,我们将在注册其他类型(如QueryMutation)之后添加下一行:AddType<Recipe>()

Program.cs
builder
.Services
.AddGraphQLServer()
.AddApolloFederation()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddType<Recipe>()
.RegisterService<SpotifyService>();

好了,让我们保存更改并重新启动服务器。

rover dev进程将拾取更改并负责将这些更改与recipes 组合起来。如果一切顺利,我们就可以这个新模式了!

在资源管理器中查询

跳回到https://127.0.0.1:4000,我们的本地rover dev 正在运行。

让我们开始构建一个新的,一个我们梦想的的简化版本。我们将询问特定食谱的名称及其推荐播放列表的名称。

query GetRecipeWithPlaylists {
randomRecipe {
name
recommendedPlaylists {
id
name
}
}
}
https://127.0.0.1:4000

Local router, query response

哇哦——我们正在获取数据——在烹饪食谱时可以唱的播放列表,不错!

让我们看一眼。单击Response旁边下拉箭头,选择Query Plan

图表视图显示了对recipes 的初始获取,然后是对soundtracks 的另一个获取,最后合并(或扁平化)recipe类型。单击Show plan as text

https://127.0.0.1:4000

Local router, query plan

查询计划
QueryPlan {
Sequence {
Fetch(service: "recipes") {
{
recipe(id: "rec3j49yFpY2uRNM1") {
__typename
id
name
}
}
},
Flatten(path: "recipe") {
Fetch(service: "soundtracks") {
{
... on Recipe {
__typename
id
}
} =>
{
... on Recipe {
recommendedPlaylists {
id
name
}
}
}
},
},
},
}

这里我们获得更多详细信息。首先,发送到recipes ,以获取食谱的__typenameidname。我们没有在原始中包含__typenameid,但需要它们来进行中的下一步,以构建表示形式Recipe

将该表示形式发送到soundtracks ,后者使用这些信息来识别Recipe的该实例,并为其贡献更多:特别是recommendedPlaylists

太棒了!我们的recipessoundtracks服务现在正在协同处理同一个Recipe 。每个都贡献自己的,而为我们打包响应。

练习

判断正误:在 Hot Chocolate 中,引用解析器函数必须命名为 ReferenceResolver

关键要点

  • 在 Hot Chocolate 中,我们使用[Key]属性来定义的键,并使用[ReferenceResolver]属性来定义引用函数。
  • 在 Hot Chocolate 中,实体需要注册到

接下来

我们对音乐的推荐仍然很弱。事实上,它们一点也不像推荐——它们是硬编码的播放列表对象!我们还没有真正使用任何特定食谱的数据来确定我们向潜在厨师用户推荐的播放列表。在下一课中,我们将深入探讨与联合相关的,并加强我们的音轨建议。

上一页

分享您对本课的疑问和意见

本课程目前处于

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

您需要一个 GitHub 帐户才能在下面发布。没有帐户吗? 请在 Odyssey 论坛上发布。