基于 GUID 的 HotChocolate GraphQL 过滤
Posted
技术标签:
【中文标题】基于 GUID 的 HotChocolate GraphQL 过滤【英文标题】:HotChocolate GraphQL filtering on GUID 【发布时间】:2021-11-25 19:59:38 【问题描述】:我对 GraphQL 的了解非常有限,因为我仍在学习过程中。现在我偶然发现了一个问题,如果没有一些帮助,我无法自己解决。
我在服务中使用 HotChocolate。
我有一个 ConsumerProductCategory
类,Guid
是 Id
,它的父类也是 ConsumerProductCategory
(想想类别 > 子类别 > ...)
现在我想获取特定类别的子类别,在 linq 中你会写:
.Where(cat => cat.Parent.Id == id)
首先让我们从我们的类开始:
public class BaseViewModel : INode
public virtual Guid Id get; set;
public class ConsumerProductCategory : BaseViewModel
public ConsumerProductCategory()
public string Name get; set;
[UsePaging]
[UseFiltering]
[UseSorting]
public List<ConsumerProduct> Products get; set; = new List<ConsumerProduct>();
public ConsumerProductCategoryImage Image get; set;
public ConsumerProductCategory Parent get; set; = null;
public bool HasParent => this.Parent != null;
对象类型定义如下:
public class ConsumerProductCategoryType : ObjectType<ConsumerProductCategory>
protected override void Configure(IObjectTypeDescriptor<ConsumerProductCategory> descriptor)
descriptor
.Name(nameof(ConsumerProductCategory));
descriptor
.Description("Categories.");
descriptor
.Field(x => x.Id)
//.Type<UuidType>()
.Type<IdType>()
.Description($"nameof(ConsumerProductCategory) Id.");
descriptor
.Field(x => x.Name)
.Type<StringType>()
.Description($"nameof(ConsumerProductCategory) name.");
descriptor
.Field(x => x.Parent)
.Description($"nameof(ConsumerProductCategory) parent category.");
descriptor
.Field(x => x.Products)
.Description($"nameof(ConsumerProductCategory) products.");
descriptor
.ImplementsNode()
.IdField(t => t.Id)
.ResolveNode((context, id) => context.Service<IConsumerProductCategoryService>().GetByIdAsync(id));
获取“主要”类别的查询如下:
query GetAllCategories
consumerProductCategories(
#request: searchTerm: "2"
first: 10
after: null
where: hasParent: eq: false
order:
name: ASC
)
nodes
id
name
image
url
alt
pageInfo
endCursor
hasNextPage
这会返回这个结果:
"data":
"consumerProductCategories":
"nodes": [
"id": "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2EyOTYxNmRlMWMzMjQ4ZTU4YTU2YzRjYjdhMGQ5NmY5",
"name": "Category 1",
"image":
"url": "https://picsum.photos/200",
"alt": "Category 1 Image"
,
"id": "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2NmZWI0YzNiMGQyNjQyOWI4MGU0MmQ1NGNjYWE1N2Q4",
"name": "Category 2",
"image":
"url": "https://picsum.photos/200",
"alt": "Category 2 Image"
,
"id": "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2I0MjhjYWE2NGMxNTQ4MTdiMjM1ZWFhZWU3OGRhYWYz",
"name": "Category 3",
"image":
"url": "https://picsum.photos/200",
"alt": "Category 3 Image"
],
"pageInfo":
"endCursor": "Mg==",
"hasNextPage": false
我注意到的第一件事是 Id (Guid) 被更改为一些 base64 编码的字符串。
很奇怪,但如果我这样做:
query
node(
id: "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2EyOTYxNmRlMWMzMjQ4ZTU4YTU2YzRjYjdhMGQ5NmY5"
)
... on ConsumerProductCategory
id
name
这完全有效,结果:
"data":
"node":
"id": "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2EyOTYxNmRlMWMzMjQ4ZTU4YTU2YzRjYjdhMGQ5NmY5",
"name": "Category 1"
但是,现在我想过滤 Parent.Id,
query GetSubcategories
consumerProductCategories(
first: 10
after: null
where: parent: id: eq: "Q29uc3VtZXJQcm9kdWN0Q2F0ZWdvcnkKZ2NmZWI0YzNiMGQyNjQyOWI4MGU0MmQ1NGNjYWE1N2Q4"
order:
name: ASC
)
nodes
id
name
image
url
alt
parent
id
pageInfo
endCursor
hasNextPage
这给出了一个错误,即我执行“eq”的字段类型不正确,这是有道理的,因为在数据中它实际上是一个 Guid。
结果:
"errors": [
"message": "The specified value type of field `eq` does not match the field type.",
"locations": [
"line": 5,
"column": 31
],
"path": [
"consumerProductCategories"
],
"extensions":
"fieldName": "eq",
"fieldType": "UUID",
"locationType": "UUID",
"specifiedBy": "http://spec.graphql.org/June2018/#sec-Values-of-Correct-Type"
]
我明白为什么它会给我这个错误,但我不知道如何解决这个问题。
我在 Google 上到处找,但没有找到类似的问题,在 HotChocolate 的官方文档中,我真的找不到这个问题的解决方案。
谁能指出我正确的方向?
顺便说一句,将这些“自动生成”的 base64 字符串用作 Id 是一种好习惯,还是有某种方法可以指定不应该发生这种生成并实际返回 Guid?
提前致谢!
【问题讨论】:
【参考方案1】:好的,我可以回答我自己的问题,基本上还不支持:github
我现在所做的只是在基类中添加第二个 Guid:
这会导致:
【讨论】:
以上是关于基于 GUID 的 HotChocolate GraphQL 过滤的主要内容,如果未能解决你的问题,请参考以下文章
如何在 GraphQL HotChocolate 中实现订阅?
HotChocolate 突变输入类型使用 int 而不是 ID