public async Task ExecutePersistedQuery_NotFound() { // arrange var queryId = Guid.NewGuid().ToString("N"); var storage = new RedisQueryStorage(_database); await storage.WriteQueryAsync(queryId, new QuerySourceText("{ __typename }")); IRequestExecutor executor = await new ServiceCollection() .AddGraphQL() .AddQueryType(c => c.Name("Query").Field("a").Resolve("b")) .AddRedisQueryStorage(s => _database) .UseRequest(n => async c => { await n(c); if (c.IsPersistedDocument && c.Result is IQueryResult r) { c.Result = QueryResultBuilder .FromResult(r) .SetExtension("persistedDocument", true) .Create(); } }) .UsePersistedQueryPipeline() .BuildRequestExecutorAsync(); // act IExecutionResult result = await executor.ExecuteAsync(new QueryRequest(queryId : "does_not_exist")); // assert result.MatchSnapshot(); }
protected IRequestExecutor CreateSchema <TEntity, T>( TEntity[] entities, FilterConvention?convention = null, bool withPaging = false) where TEntity : class where T : FilterInputType <TEntity> { convention ??= new FilterConvention(x => x.AddDefaults().BindRuntimeType <TEntity, T>()); Func <IResolverContext, IEnumerable <TEntity> >?resolver = BuildResolver(entities); ISchemaBuilder builder = SchemaBuilder.New() .AddConvention <IFilterConvention>(convention) .AddFiltering() .AddQueryType( c => { ApplyConfigurationToField <TEntity, T>( c.Name("Query").Field("root").Resolver(resolver), withPaging); ApplyConfigurationToField <TEntity, T>( c.Name("Query") .Field("rootExecutable") .Resolver( ctx => resolver(ctx).AsExecutable()), withPaging); }); ISchema schema = builder.Create(); return(new ServiceCollection() .Configure <RequestExecutorSetup>( Schema.DefaultName, o => o.Schema = schema) .AddGraphQL() .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("sql", out var queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("sql", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync() .Result); }
public async Task ClassDataLoader() { // arrange IRequestExecutor executor = await CreateExecutorAsync(c => c .AddQueryType <Query>() .AddDataLoader <ITestDataLoader, TestDataLoader>() .UseRequest(next => async context => { await next(context); var dataLoader = context.Services .GetRequiredService <IDataLoaderRegistry>() .GetOrRegister <TestDataLoader>(() => throw new Exception()); context.Result = QueryResultBuilder .FromResult((IQueryResult)context.Result) .AddExtension("loads", dataLoader.Loads) .Create(); }) .UseDefaultPipeline()); // act var results = new List <IExecutionResult>(); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ a: withDataLoader(key: ""a"") b: withDataLoader(key: ""b"") bar { c: withDataLoader(key: ""c"") } }") .Create())); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ a: withDataLoader(key: ""a"") }") .Create())); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ c: withDataLoader(key: ""c"") }") .Create())); // assert results.MatchSnapshot(); }
public Task <IReadOnlyQueryResult> OnResponseReceivedAsync( IReadOnlyQueryRequest request, HttpResponseMessage response, IReadOnlyQueryResult result) { return(Task.FromResult( QueryResultBuilder.FromResult(result) .SetContextData("foo", "bar") .Create())); }
protected async Task <IRequestExecutor> CreateSchemaAsync <TEntity, T>( TEntity[] entities, FilterConvention?convention = null) where TEntity : class where T : FilterInputType <TEntity> { Func <IResolverContext, IEnumerable <TEntity> > resolver = await BuildResolverAsync(entities); return(await new ServiceCollection() .AddGraphQL() .AddFiltering() .AddSpatialTypes() .AddSpatialFiltering() .AddQueryType( c => c .Name("Query") .Field("root") .Resolve(resolver) .Use( next => async context => { await next(context); if (context.Result is IQueryable <TEntity> queryable) { try { context.ContextData["sql"] = queryable.ToQueryString(); } catch (Exception) { context.ContextData["sql"] = "EF Core 3.1 does not support ToQueryString officially"; } } }) .UseFiltering <T>()) .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("sql", out var queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("sql", queryString) .Create(); } }) .UseDefaultPipeline() .BuildRequestExecutorAsync()); }
protected IRequestExecutor CreateSchema <TEntity, T>( TEntity[] entities, MongoResource mongoResource, bool withPaging = false) where TEntity : class where T : FilterInputType <TEntity> { Func <IResolverContext, IExecutable <TEntity> > resolver = BuildResolver( mongoResource, entities); return(new ServiceCollection() .AddGraphQL() .AddObjectIdConverters() .AddFiltering(x => x.BindRuntimeType <TEntity, T>().AddMongoDbDefaults()) .AddQueryType( c => c .Name("Query") .Field("root") .Resolve(resolver) .Use( next => async context => { await next(context); if (context.Result is IExecutable executable) { context.ContextData["query"] = executable.Print(); } }) .UseFiltering <T>()) .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("query", out var queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("query", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync() .GetAwaiter() .GetResult()); }
public async Task ClassDataLoader_Resolve_From_DependencyInjection() { // arrange IRequestExecutor executor = await CreateExecutorAsync(c => c .AddQueryType <Query>() .AddDataLoader <ITestDataLoader, TestDataLoader>() .UseRequest(next => async context => { await next(context); var dataLoader = (TestDataLoader)context.Services.GetRequiredService <ITestDataLoader>(); context.Result = QueryResultBuilder .FromResult((IQueryResult)context.Result) .AddExtension("loads", dataLoader.Loads) .Create(); }) .UseDefaultPipeline()); // act var results = new List <IExecutionResult>(); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ a: dataLoaderWithInterface(key: ""a"") b: dataLoaderWithInterface(key: ""b"") }") .Create())); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ a: dataLoaderWithInterface(key: ""a"") }") .Create())); results.Add(await executor.ExecuteAsync( QueryRequestBuilder.New() .SetQuery( @"{ c: dataLoaderWithInterface(key: ""c"") }") .Create())); // assert results.MatchSnapshot(); }
private ValueTask <IRequestExecutor> CreateSchemaAsync() { return(new ServiceCollection() .AddGraphQL() .AddMongoDbPagingProviders() .AddFiltering(x => x.AddMongoDbDefaults()) .AddQueryType( descriptor => { descriptor .Field("foos") .Resolve(BuildResolver(_resource, foos)) .Type <ListType <ObjectType <Foo> > >() .Use( next => async context => { await next(context); if (context.Result is IExecutable executable) { context.ContextData["query"] = executable.Print(); } }) .UsePaging <ObjectType <Foo> >( options: new PagingOptions { IncludeTotalCount = true }); }) .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("query", out object?queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("query", queryString) .Create(); } }) .ModifyRequestOptions(x => x.IncludeExceptionDetails = true) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync()); }
public void Dispose() { if (!_disposed) { DateTime endTime = _timestampProvider.UtcNow(); _builder.SetRequestDuration(endTime - _startTime); if (_context.Result is IReadOnlyQueryResult queryResult) { _context.Result = QueryResultBuilder.FromResult(queryResult) .AddExtension(_extensionKey, _builder.Build()) .Create(); } _disposed = true; } }
private static IRequestExecutor CreateSchema <TEntity>( Func <IExecutable <TEntity> > resolver) where TEntity : class { return(new ServiceCollection() .AddGraphQL() .AddFiltering(x => x.AddMongoDbDefaults()) .AddQueryType( c => c .Name("Query") .Field("root") .Type <ListType <ObjectType <TEntity> > >() .Resolver( async ctx => await new ValueTask <IExecutable <TEntity> >(resolver())) .Use( next => async context => { await next(context); if (context.Result is IExecutable executable) { context.ContextData["query"] = executable.Print(); } }) .UseFiltering <FilterInputType <TEntity> >()) .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("query", out object?queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("query", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync() .GetAwaiter() .GetResult()); }
public async Task ExecutePersistedQuery() { // arrange var queryId = Guid.NewGuid().ToString("N"); DocumentNode document = Utf8GraphQLParser.Parse("{ __typename }"); IServiceProvider services = new ServiceCollection() .AddMemoryCache() .AddGraphQL() .AddQueryType(c => c.Name("Query").Field("a").Resolve("b")) .AddInMemoryQueryStorage() .UseRequest(n => async c => { await n(c); if (c.IsPersistedDocument && c.Result is IQueryResult r) { c.Result = QueryResultBuilder .FromResult(r) .SetExtension("persistedDocument", true) .Create(); } }) .UsePersistedQueryPipeline() .Services .BuildServiceProvider(); var cache = services.GetRequiredService <IMemoryCache>(); IRequestExecutor executor = await services.GetRequestExecutorAsync(); await cache.GetOrCreate(queryId, item => Task.FromResult(new QueryDocument(document))); // act IExecutionResult result = await executor.ExecuteAsync(new QueryRequest(queryId : queryId)); // assert result.ToJson().MatchSnapshot(); }
public static ValueTask <IRequestExecutor> CreateExecptionExecutor( this IRequestExecutorBuilder builder) { return(builder.UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("ex", out object?queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("ex", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync()); }
public async Task ExecutePersistedQuery_ApplicationDI_Default() { // arrange var queryId = Guid.NewGuid().ToString("N"); var storage = new RedisQueryStorage(_database); await storage.WriteQueryAsync(queryId, new QuerySourceText("{ __typename }")); IRequestExecutor executor = await new ServiceCollection() // we register the multiplexer on the application services .AddSingleton(_multiplexer) .AddGraphQL() .AddQueryType(c => c.Name("Query").Field("a").Resolve("b")) // and in the redis storage setup refer to that instance. .AddRedisQueryStorage() .UseRequest(n => async c => { await n(c); if (c.IsPersistedDocument && c.Result is IQueryResult r) { c.Result = QueryResultBuilder .FromResult(r) .SetExtension("persistedDocument", true) .Create(); } }) .UsePersistedQueryPipeline() .BuildRequestExecutorAsync(); // act IExecutionResult result = await executor.ExecuteAsync(new QueryRequest(queryId : queryId)); // assert result.MatchSnapshot(); }
public async Task ExecutePersistedQuery_NotFound() { // arrange var queryId = Guid.NewGuid().ToString("N"); var cacheDirectory = IO.Path.GetTempPath(); var cachedQuery = IO.Path.Combine(cacheDirectory, queryId + ".graphql"); await File.WriteAllTextAsync(cachedQuery, "{ __typename }"); IRequestExecutor executor = await new ServiceCollection() .AddGraphQL() .AddQueryType(c => c.Name("Query").Field("a").Resolve("b")) .AddFileSystemQueryStorage(cacheDirectory) .UseRequest(n => async c => { await n(c); if (c.IsPersistedDocument && c.Result is IQueryResult r) { c.Result = QueryResultBuilder .FromResult(r) .SetExtension("persistedDocument", true) .Create(); } }) .UsePersistedQueryPipeline() .BuildRequestExecutorAsync(); // act IExecutionResult result = await executor.ExecuteAsync(new QueryRequest(queryId : "does_not_exist")); // assert File.Delete(cachedQuery); result.MatchSnapshot(); }
protected IRequestExecutor CreateSchema <TEntity, T>( TEntity[] entities, FilterConvention?convention = null) where TEntity : class where T : FilterInputType <TEntity> { convention ??= new FilterConvention(x => x.AddDefaults().BindRuntimeType <TEntity, T>()); Func <IResolverContext, IEnumerable <TEntity> >?resolver = BuildResolver(entities); ISchemaBuilder builder = SchemaBuilder.New() .AddConvention <IFilterConvention>(convention) .AddFiltering() .AddQueryType( c => c .Name("Query") .Field("root") .Resolver(resolver) .Use(next => async context => { await next(context); if (context.Result is IQueryable <TEntity> queryable) { try { context.ContextData["sql"] = queryable.ToQueryString(); } catch (Exception) { context.ContextData["sql"] = "EF Core 3.1 does not support ToQuerString offically"; } } }) .UseFiltering <T>()); ISchema?schema = builder.Create(); return(new ServiceCollection() .Configure <RequestExecutorFactoryOptions>(Schema.DefaultName, o => o.Schema = schema) .AddGraphQL() .UseRequest(next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("sql", out var queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("sql", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync() .Result); }
public IRequestExecutor CreateSchema <TEntity>( TEntity[] entities, ProjectionProvider?provider = null, Action <ModelBuilder>?onModelCreating = null, bool usePaging = false, bool useOffsetPaging = false, INamedType?objectType = null, Action <ISchemaBuilder>?configure = null) where TEntity : class { provider ??= new QueryableProjectionProvider(x => x.AddDefaults()); var convention = new ProjectionConvention(x => x.Provider(provider)); Func <IResolverContext, IQueryable <TEntity> > resolver = BuildResolver(onModelCreating, entities); ISchemaBuilder builder = SchemaBuilder.New(); if (objectType is not null) { builder.AddType(objectType); } configure?.Invoke(builder); builder .AddConvention <IProjectionConvention>(convention) .AddProjections() .AddFiltering() .AddSorting() .AddQueryType( new ObjectType <StubObject <TEntity> >( c => { c.Name("Query"); ApplyConfigurationToFieldDescriptor <TEntity>( c.Field(x => x.Root).Resolve(resolver), usePaging, useOffsetPaging); ApplyConfigurationToFieldDescriptor <TEntity>( c.Field("rootExecutable") .Resolve(ctx => resolver(ctx).AsExecutable()), usePaging, useOffsetPaging); })); builder.ModifyOptions(o => o.ValidatePipelineOrder = false); ISchema schema = builder.Create(); return(new ServiceCollection() .Configure <RequestExecutorSetup>(Schema.DefaultName, o => o.Schema = schema) .AddGraphQL() .UseRequest( next => async context => { await next(context); if (context.Result is IReadOnlyQueryResult result && context.ContextData.TryGetValue("sql", out object?queryString)) { context.Result = QueryResultBuilder .FromResult(result) .SetContextData("sql", queryString) .Create(); } }) .UseDefaultPipeline() .Services .BuildServiceProvider() .GetRequiredService <IRequestExecutorResolver>() .GetRequestExecutorAsync() .Result); }