来自多个来源的热巧克力顶级属性

问题描述 投票:0回答:2

我有一个实体(客户)需要从多个来源提取数据。该架构大致如下所示:

{
   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

graphql .net-6.0 hotchocolate
2个回答
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;
   }
}

0
投票

您可以使用

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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.