我有一个实体(客户)需要从多个来源提取数据。该架构大致如下所示:
{
id: string
name: string
address: string
contact: string
status: string
}
id
、name
和 address
来自 EF 数据上下文。 contact
和 status
字段来自 single REST 端点,如下所示:
GET /url/customer?id=1234
{
id: '1234'
contact: '[email protected]'
status: 'ACTIVE'
}
如果我将
contact
和 status
放入单个字段/对象中(即 ContactStatus
),那么这将是为 Customer
创建扩展的简单情况。但这些字段并不相关,应该被视为不同的top-level字段。
有没有办法确保在获取所有值时仅调用 REST 端点一次?本质上在获取一个或另一个字段时可能会解析这两个字段?
Hot Chocolate v12.15.0
、net6.0
是的,您可以使用批处理 API 来执行此操作
创建一个从其余端点加载数据的 DataLoader。通过这种方式,您还可以优化从其余端点的获取(如果端点支持 /url/customer?ids=1234,2345,5930 等内容)
例如
class YourDataloader extends BatchDataLoader<int, AdditionalCustomerData>
那么你就可以做
[ExtendObjectType<Customer>]
public class CustomerExtensions
{
public Task<string> GetContactAsync(
[Parent]Customer customer,
YourDataloader dataloader)
{
var result = await dataloader.LoadAsync(customer.Id);
return result.Contact;
}
public Task<Status> GetStatusAsync(
[Parent]Customer customer,
YourDataloader dataloader)
{
var result = await dataloader.LoadAsync(customer.Id);
return result.Status;
}
}
您可以使用
CacheDataLoader
确保您仅为每个客户调用 REST 端点一次。
如果在查询图中同一实体被解析两次,我们只会从数据源加载一次。 (来源)
示例(未测试):
public class Customer
{
// Other properties/constructors/etc. not shown...
public async Task<string> Contact(IResolverContext context, CustomerService service)
{
var contactStatus = await this.LoadContactStatus(context, service);
return contactStatus.Contact;
}
public async Task<string> Status(IResolverContext context, CustomerService service)
{
var contactStatus = await this.LoadContactStatus(context, service);
return contactStatus.Status;
}
private async Task<ContactStatus> LoadContactStatus(IResolverContext context, CustomerService service)
{
var loader = context.CacheDataLoader<string, ContactStatus>((key, cancellationToken) => service.GetContactStatus(key), "getContactStatus");
return await loader.LoadAsync(this.Id);
}
}