我有一种感觉,它必须是强类型的,一种或另一种方式,并且很好奇我是否可以使用相同的查询来完成两者,我想要这样的东西:
{
accounts(accountId: [1,2,3]) {
...
}
}
并且还能够进行同样的调用,将其视为普通 int:
{
accounts(accountId: 1) {
...
}
}
我有一种感觉,它必须是强类型的,一种或另一种方式,并且很好奇我是否可以使用相同的查询来完成两者,我想要这样的东西:
{
accounts(accountId: [1,2,3]) {
...
}
}
并且还能够进行同样的调用,将其视为普通 int:
{
accounts(accountId: 1) {
...
}
}
List 是一种包装类型,它包装了另一种类型,但它本身就是一种不同的类型。所以Int
和[Int]
是两种不同的类型。字段或参数必须只有一种类型,因此它只能具有类型Int
或类型[Int]
——不能同时具有两者。
但是,您可以利用 GraphQL 如何强制 List 输入值。从规范:
如果作为输入传递给列表类型的值不是列表且不是空值,则输入强制的结果是大小为 1 的列表,其中单个项目值是列表项类型的输入强制的结果在提供的值上(注意这可能递归地应用于嵌套列表)。
换句话说,如果 的类型accountId
是[Int]
(或[Int!]
或[Int!]!
),客户端仍然可以将单个整数作为值而不是数组传递。在这种情况下,该值将被强制转换为具有单个值(传入的那个)的数组。
扩展 Daniel Reardon 的回答:不幸的是,不可能使用不同的参数查询相同的字段。对于这种情况,推荐的技术是使用别名:
https://graphql.org/learn/queries/#aliases
但是,您可以设计您的 API 以根据您传递给它的数组返回不同的结果。例如,如果数组中只有一项,则可以仅返回一条记录,如果有很多,则可以返回许多记录,或者如果数组为空,则可以返回所有记录。
这是一些可能看起来像的假设代码:
public IEnumerable<Accounts> GetAccounts(int[] accountIds)
{
// if no items in array
if (accountIds.Length == 0)
{
// return all accounts
return Accounts.ToList();
}
// return only accounts that are in accountIds array
// if only one item is in array, then an IEnumerable with only one item will be returned
return Accounts
.Where(b => accountIds.Contains(b.AccountId))
.ToList();
}
如果传递了一个只有一个 ID 的数组,则 Star Wars API 示例中的 Hot Chocolate 的 GetCharacters(int[] ids) 方法也将只返回一个字符,如果数组中有多个项目,则返回多个:
public IEnumerable<ICharacter> GetCharacters(int[] ids)
{
foreach (int id in ids)
{
if (_characters.TryGetValue(id, out ICharacter? c))
{
yield return c;
}
}
}