کوئری های پیشرفته، Error Handling و Data Loader در GraphQL
نویسنده: ابوالفضل روشن ضمیر
تاریخ: ۱۳۹۸/۰۴/۱۹ ۲۲:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class AccountType : ObjectGraphType<Account>
{
public AccountType()
{
Field(x => x.Id, type: typeof(IdGraphType)).Description("Id property from the account object.");
Field(x => x.Description).Description("Description property from the account object.");
Field(x => x.OwnerId, type: typeof(IdGraphType)).Description("OwnerId property from the account object.");
}
} public interface IAccountRepository
{
IEnumerable<Account> GetAllAccountsPerOwner(Guid ownerId);
}
public class AccountRepository : IAccountRepository
{
private readonly ApplicationContext _context;
public AccountRepository(ApplicationContext context)
{
_context = context;
}
public IEnumerable<Account> GetAllAccountsPerOwner(Guid ownerId) => _context.Accounts
.Where(a => a.OwnerId.Equals(ownerId))
.ToList();
} public class OwnerType : ObjectGraphType<Owner>
{
public OwnerType(IAccountRepository repository)
{
Field(x => x.Id, type: typeof(IdGraphType)).Description("Id property from the owner object.");
Field(x => x.Name).Description("Name property from the owner object.");
Field(x => x.Address).Description("Address property from the owner object.");
Field<ListGraphType<AccountType>>(
"accounts",
resolve: context => repository.GetAllAccountsPerOwner(context.Source.Id)
);
}
}
https://localhost:5001/ui/playground
{
owners{
id,
name,
address,
accounts{
id,
description,
ownerId
}
}
} public class AccountTypeEnumType : EnumerationGraphType<TypeOfAccount>
{
public AccountTypeEnumType()
{
Name = "Type";
Description = "Enumeration for the account type object.";
}
} public class AccountType : ObjectGraphType<Account>
{
public AccountType()
{
...
Field<AccountTypeEnumType>("Type", "Enumeration for the account type object.");
}
} {
owners{
id,
name,
address,
accounts{
id,
description,
type,
ownerId
}
}
}
public interface IAccountRepository
{
...
Task<ILookup<Guid, Account>> GetAccountsByOwnerIds(IEnumerable<Guid> ownerIds);
} public class AccountRepository : IAccountRepository
{
...
public async Task<ILookup<Guid, Account>> GetAccountsByOwnerIds(IEnumerable<Guid> ownerIds)
{
var accounts = await _context.Accounts.Where(a => ownerIds.Contains(a.OwnerId)).ToListAsync();
return accounts.ToLookup(x => x.OwnerId);
}
} public class OwnerType : ObjectGraphType<Owner>
{
public OwnerType(IAccountRepository repository, IDataLoaderContextAccessor dataLoader)
{
...
Field<ListGraphType<AccountType>>(
"accounts",
resolve: context =>
{
var loader = dataLoader.Context.GetOrAddCollectionBatchLoader<Guid, Account>("GetAccountsByOwnerIds", repository.GetAccountsByOwnerIds);
return loader.LoadAsync(context.Source.Id);
});
}
} services.AddGraphQL(o => { o.ExposeExceptions = false; })
.AddGraphTypes(ServiceLifetime.Scoped)
.AddDataLoader();
public interface IOwnerRepository
{
...
Owner GetById(Guid id);
}
public class OwnerRepository : IOwnerRepository
{
...
Owner GetById(Guid id) => _context.Owners.SingleOrDefault(o => o.Id.Equals(id));
} public class AppQuery : ObjectGraphType
{
public AppQuery(IOwnerRepository repository)
{
...
Field<OwnerType>(
"owner",
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "ownerId" }),
resolve: context =>
{
var id = context.GetArgument<Guid>("ownerId");
return repository.GetById(id);
}
);
}
} Field<OwnerType>(
"owner",
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "ownerId" }),
resolve: context =>
{
Guid id;
if (!Guid.TryParse(context.GetArgument<string>("ownerId"), out id))
{
context.Errors.Add(new ExecutionError("Wrong value for guid"));
return null;
}
return repository.GetById(id);
}
); {
owner(ownerId:"6f513773-be46-4001-8adc-2e7f17d52d83"){
id,
name,
address,
accounts{
id,
description,
type,
ownerId
}
} string name = context.GetArgument<string>("name"); {
owner(ownerId:"53270061-3ba1-4aa6-b937-1f6bc57d04d2", name:"ANDY") {
...
}
} {
first:owners{
ownerId:id,
ownerName:name,
ownerAddress:address,
ownerAccounts:accounts
{
accountId:id,
accountDescription:description,
accountType:type
}
},
second:owners{
ownerId:id,
ownerName:name,
ownerAddress:address,
ownerAccounts:accounts
{
accountId:id,
accountDescription:description,
accountType:type
}
}
} fragment SampleName on Type{
...
} {
first:owners{
...ownerFields
},
second:owners{
...ownerFields
},
...
}
fragment ownerFields on OwnerType{
ownerId:id,
ownerName:name,
ownerAddress:address,
ownerAccounts:accounts
{
accountId:id,
accountDescription:description,
accountType:type
}
} query OwnerQuery($ownerId:ID!)
{
owner(ownerId:$ownerId){
id,
name,
address,
accounts{
id,
description,
type
}
}
} {
"ownerId":"6f513773-be46-4001-8adc-2e7f17d52d83"
}