public ContentPageGraphType( IDataLoaderContextAccessor dataLoaderContextAccessor, IMetaFieldServiceProvider metaFieldServiceProvider, IMetaFieldService metaFieldService, IMetaFieldLookupService metaFieldLookupService, IContentPageService contentPageService, IContentPageLookupService contentPageLookupService ) { Name = "ContentPage"; Field <StringGraphType, string>() .Name("Id") .Description("Globally unique identifier, eg: gid://ContentPage/1000") .Resolve(ctx => ctx.Source.Id); Field <StringGraphType, string>() .Name("ParentId") .Description("Globally unique identifier of parent, 'gid://' if none") .Resolve(ctx => ctx.Source.ParentId); Field <StringGraphType, string>() .Name("Handle") .Description("A human-friendly unique string for the content page") .Resolve(ctx => { var userContext = (StorefrontGraphUserContext)ctx.UserContext; return(ctx.Source.Handles .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode) ?.Value); }); Field <StringGraphType, string>() .Name("Title") .Description("The title of the content page") .Resolve(ctx => { var userContext = (StorefrontGraphUserContext)ctx.UserContext; return(ctx.Source.Titles .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode) ?.Value); }); Field <StringGraphType, string>() .Name("Url") .Description("The url of the content page") .Resolve(ctx => { var userContext = (StorefrontGraphUserContext)ctx.UserContext; return(ctx.Source.Urls .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode) ?.Value); }); Field <StringGraphType, string>() .Name("Type") .Description("The type of the content page") .Resolve(ctx => ctx.Source.Type); Field <StringGraphType, string>() .Name("Description") .Description("The description of the content page") .Resolve(ctx => { var userContext = (StorefrontGraphUserContext)ctx.UserContext; return(ctx.Source.Descriptions .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode) ?.Value); }); Field <DateTimeGraphType, DateTime>() .Name("CreatedAt") .Description("The timestamp of content page creation") .Resolve(ctx => ctx.Source.CreatedAt.ToDateTime()); Field <DateTimeGraphType, DateTime>() .Name("UpdatedAt") .Description("The timestamp of the latest content page update") .Resolve(ctx => ctx.Source.UpdatedAt.ToDateTime()); Field <ImageGraphType, Image>() .Name("PrimaryImage") .Description("The primary image of the content page") .Resolve(ctx => ctx.Source.PrimaryImage); #region Meta-fields Field <MetaFieldGraphType, MetaField>() .Name("MetaField") .Description("Connection to a specific meta-field") .Argument <NonNullGraphType <StringGraphType> >("namespace", "Namespace of the meta-field") .Argument <NonNullGraphType <StringGraphType> >("name", "Name of the meta-field") .ResolveAsync(async ctx => { if (!metaFieldServiceProvider.IsEnabled) { throw new ExecutionError("Meta-fields not supported."); } var result = await metaFieldService.GetBySearchAsync( ctx.Source.Id, ctx.GetArgument <string>("namespace"), ctx.GetArgument <string>("name")); return(result.FirstOrDefault()); }); Field <ListGraphType <MetaFieldGraphType>, IList <MetaField> >() .Name("MetaFields") .Description("Connection to a all meta-fields") .ResolveAsync(ctx => { if (!metaFieldServiceProvider.IsEnabled) { throw new ExecutionError("Meta-fields not supported."); } var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, IList <MetaField> >("MetaField.LookupByParentIdsAsync", metaFieldLookupService.LookupByParentIdsAsync); return(loader.LoadAsync(ctx.Source.Id)); }); #endregion Meta-fields #region Content pages Field <ContentPageGraphType, ContentPage>() .Name("Parent") .ResolveAsync(ctx => { if (string.IsNullOrEmpty(ctx.Source.ParentId)) { return(null); } var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, ContentPage>("ContentPage.LookupByIdAsync", contentPageLookupService.LookupByIdAsync); return(loader.LoadAsync(ctx.Source.ParentId)); }); Connection <ContentPageGraphType>() .Name("Children") .Unidirectional() .Argument <StringGraphType>("query", "The search query to filter children by") .Argument <ContentPageSortKeyGraphType>("sortKey", "The key to sort the underlying list by") .Argument <StringGraphType>("reverse", "Reverse the order of the underlying list") .ResolveAsync(async ctx => { var userContext = (StorefrontGraphUserContext)ctx.UserContext; var result = await contentPageService.GetBySearchAsync( ctx.GetArgument <string>("query"), userContext.LanguageCode, ctx.Source.Id, ctx.GetArgument <string>("after"), ctx.GetArgument <int>("first", 24), ctx.GetArgument <ContentPageSortKey>("sortKey"), ctx.GetArgument <bool>("reverse")); return(result.ToGraphConnection()); }); #endregion Content pages }
public StorefrontGraphQuery( IDataLoaderContextAccessor dataLoaderContextAccessor, ILanguageProvider languageProvider, ICurrencyProvider currencyProvider, IContentPageServiceProvider contentPageServiceProvider, INavigationServiceProvider navigationServiceProvider, ICategoryServiceProvider categoryServiceProvider, IProductServiceProvider productServiceProvider, IContentPageService contentPageService, IContentPageLookupService contentPageLookupService, INavigationLookupService navigationLookupService, ICategoryService categoryService, ICategoryLookupService categoryLookupService, IProductService productService, IProductLookupService productLookupService) { Name = "Query"; #region Languages Field <ListGraphType <LanguageGraphType>, IList <string> >() .Name("Languages") .Description("The languages supported") .Resolve(ctx => languageProvider.Languages); #endregion Languages #region Currencies Field <ListGraphType <CurrencyGraphType>, IList <NodaMoney.Currency> >() .Name("Currencies") .Description("The currencies supported") .Resolve(ctx => currencyProvider.Currencies .Select(NodaMoney.Currency.FromCode) .ToList()); #endregion Currencies #region Content Pages Field <ContentPageGraphType, ContentPage>() .Name("ContentPage") .Argument <StringGraphType>("id", "Id of the content page") .Argument <StringGraphType>("handle", "Handle of the content page") .ResolveAsync(ctx => { if (!contentPageServiceProvider.IsEnabled) { throw new ExecutionError("Content pages not supported."); } if (ctx.HasArgument("id")) { var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, ContentPage>("ContentPage.LookupByIdAsync", contentPageLookupService.LookupByIdAsync); return(loader.LoadAsync(ctx.GetArgument <string>("id"))); } if (ctx.HasArgument("handle")) { var userContext = (StorefrontGraphUserContext)ctx.UserContext; var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, ContentPage>("ContentPage.LookupByHandleAsync", handles => contentPageLookupService.LookupByHandleAsync(handles, userContext.LanguageCode)); return(loader.LoadAsync(ctx.GetArgument <string>("handle"))); } return(null); }); Connection <ContentPageGraphType>() .Name("ContentPages") .Unidirectional() .Argument <StringGraphType>("query", "The search query to filter results by") .Argument <ContentPageSortKeyGraphType>("sortKey", "The key to sort the underlying list by") .Argument <StringGraphType>("reverse", "Reverse the order of the underlying list") .ResolveAsync(async ctx => { if (!contentPageServiceProvider.IsEnabled) { throw new ExecutionError("Content pages not supported."); } var userContext = (StorefrontGraphUserContext)ctx.UserContext; var result = await contentPageService.GetBySearchAsync( ctx.GetArgument <string>("query"), userContext.LanguageCode, null, ctx.GetArgument <string>("after"), ctx.GetArgument <int>("first", 24), ctx.GetArgument <ContentPageSortKey>("sortKey"), ctx.GetArgument <bool>("reverse")); return(result.ToGraphConnection()); }); #endregion Content Pages #region Navigations Field <NavigationGraphType, Navigation>() .Name("Navigation") .Argument <StringGraphType>("id", "Id of the navigation") .Argument <StringGraphType>("handle", "Handle of the navigation") .ResolveAsync(ctx => { if (!navigationServiceProvider.IsEnabled) { throw new ExecutionError("Navigations not supported."); } if (ctx.HasArgument("id")) { var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Navigation>("Navigation.LookupByIdAsync", navigationLookupService.LookupByIdAsync); return(loader.LoadAsync(ctx.GetArgument <string>("id"))); } if (ctx.HasArgument("handle")) { var userContext = (StorefrontGraphUserContext)ctx.UserContext; var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Navigation>("Navigation.LookupByHandleAsync", handles => navigationLookupService.LookupByHandleAsync(handles, userContext.LanguageCode)); return(loader.LoadAsync(ctx.GetArgument <string>("handle"))); } return(null); }); #endregion Navigations #region Categories Field <CategoryGraphType, Category>() .Name("Category") .Argument <StringGraphType>("id", "Id of the category") .Argument <StringGraphType>("handle", "Handle of the category") .ResolveAsync(ctx => { if (!categoryServiceProvider.IsEnabled) { throw new ExecutionError("Categories not supported."); } if (ctx.HasArgument("id")) { var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Category>("Category.LookupByIdAsync", categoryLookupService.LookupByIdAsync); return(loader.LoadAsync(ctx.GetArgument <string>("id"))); } if (ctx.HasArgument("handle")) { var userContext = (StorefrontGraphUserContext)ctx.UserContext; var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Category>("Category.LookupByHandleAsync", handles => categoryLookupService.LookupByHandleAsync(handles, userContext.LanguageCode)); return(loader.LoadAsync(ctx.GetArgument <string>("handle"))); } return(null); }); Connection <CategoryGraphType>() .Name("Categories") .Unidirectional() .Argument <StringGraphType>("query", "The search query to filter results by") .Argument <CategorySortKeyGraphType>("sortKey", "The key to sort the underlying list by") .Argument <StringGraphType>("reverse", "Reverse the order of the underlying list") .ResolveAsync(async ctx => { if (!categoryServiceProvider.IsEnabled) { throw new ExecutionError("Categories not supported."); } var userContext = (StorefrontGraphUserContext)ctx.UserContext; var result = await categoryService.GetBySearchAsync( ctx.GetArgument <string>("query"), userContext.LanguageCode, null, ctx.GetArgument <string>("after"), ctx.GetArgument <int>("first", 24), ctx.GetArgument <CategorySortKey>("sortKey"), ctx.GetArgument <bool>("reverse")); return(result.ToGraphConnection()); }); #endregion Categories #region Products Field <ProductGraphType, Product>() .Name("Product") .Argument <StringGraphType>("id", "Id of the category") .Argument <StringGraphType>("handle", "Handle of the category") .ResolveAsync(ctx => { if (!productServiceProvider.IsEnabled) { throw new ExecutionError("Products not supported."); } if (ctx.HasArgument("id")) { var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Product>("Product.LookupByIdAsync", productLookupService.LookupByIdAsync); return(loader.LoadAsync(ctx.GetArgument <string>("id"))); } if (ctx.HasArgument("handle")) { var userContext = (StorefrontGraphUserContext)ctx.UserContext; var loader = dataLoaderContextAccessor.Context .GetOrAddBatchLoader <string, Product>("Product.LookupByHandleAsync", handles => productLookupService.LookupByHandleAsync(handles, userContext.LanguageCode)); return(loader.LoadAsync(ctx.GetArgument <string>("handle"))); } return(null); }); Connection <ProductGraphType>() .Name("Products") .Unidirectional() .Argument <StringGraphType>("query", "The search query to filter results by") .Argument <ProductSortKeyGraphType>("sortKey", "The key to sort the underlying list by") .Argument <StringGraphType>("reverse", "Reverse the order of the underlying list") .ResolveAsync(async ctx => { if (!productServiceProvider.IsEnabled) { throw new ExecutionError("Products not supported."); } var userContext = (StorefrontGraphUserContext)ctx.UserContext; var result = await productService.GetBySearchAsync( ctx.GetArgument <string>("query"), userContext.LanguageCode, null, ctx.GetArgument <string>("after"), ctx.GetArgument <int>("first", 24), ctx.GetArgument <ProductSortKey>("sortKey"), ctx.GetArgument <bool>("reverse"), userContext.CurrencyCode); return(result.ToGraphConnection()); }); #endregion Products }