public void validate_core_schema()
        {
            var documentExecuter = new DocumentExecuter();
            var executionResult = documentExecuter.ExecuteAsync(new Schema(), null, SchemaIntrospection.IntrospectionQuery, null).Result;
            var json = new DocumentWriter(true).Write(executionResult.Data);

            json.ShouldBe(IntrospectionResult.Data);
        }
        public async Task ExecutingThenDisposing_DoesNotThrowException()
        {
            var executer = new DocumentExecuter();
            var schema = new Schema();

            await executer.ExecuteAsync(schema, null, "{noop}", null).ConfigureAwait(false);

            Should.NotThrow(() => schema.Dispose());
        }
        public void validate_non_null_schema()
        {
            var documentExecuter = new DocumentExecuter();
            var executionResult = documentExecuter.ExecuteAsync(new TestSchema(), null, InputObjectBugQuery, null).Result;
            var json = new DocumentWriter(true).Write(executionResult.Data);
            executionResult.Errors.ShouldBeNull();

            json.ShouldBe(InputObjectBugResult);
        }
 public async Task<ExecutionResult> Execute(
   Schema schema,
   object rootObject,
   string query,
   string operationName = null,
   Inputs inputs = null)
 {
     var executer = new DocumentExecuter();
     return await executer.ExecuteAsync(schema, rootObject, query, operationName);
 }
 public ExecutionResult Execute(
   Schema schema,
   object rootObject,
   string query,
   string operationName = null,
   Inputs inputs = null)
 {
     var executer = new DocumentExecuter();
     return executer.Execute(schema, rootObject, query, operationName);
 }
        public GraphQLModule(ISchema schema)
        {
            _schema = schema;

            Get["/graphql", runAsync: true] = async (_, token) =>
            {
                var queryModel = this.Bind<GraphQLQuery>();

                var executer = new DocumentExecuter();
                var queryResult = await executer.ExecuteAsync(_schema, null, queryModel.Query, null);

                return queryResult;
            ;            };
        }
    public async Task LongMaxValueShouldBeSerialized(IGraphQLTextSerializer serializer)
    {
        var documentExecuter = new DocumentExecuter();
        var executionResult  = await documentExecuter.ExecuteAsync(_ =>
        {
            _.Schema = new LongSchema();
            _.Query  = "{ testField }";
        }).ConfigureAwait(false);

        var json = serializer.Serialize(executionResult);

        executionResult.Errors.ShouldBeNull();

        json.ShouldBe(@"{
  ""data"": {
    ""testField"": 9223372036854775807
  }
}");
    }
        public void GlobalSetup()
        {
            var services = new ServiceCollection();

            services.AddSingleton <StarWarsData>();
            services.AddSingleton <StarWarsQuery>();
            services.AddSingleton <StarWarsMutation>();
            services.AddSingleton <HumanType>();
            services.AddSingleton <HumanInputType>();
            services.AddSingleton <DroidType>();
            services.AddSingleton <CharacterInterface>();
            services.AddSingleton <EpisodeEnum>();
            services.AddSingleton <ISchema, StarWarsSchema>();

            _provider = services.BuildServiceProvider();
            _schema   = _provider.GetRequiredService <ISchema>();
            //_schema = new SchemaForIntrospection();
            _executer = new DocumentExecuter();
        }
Beispiel #9
0
        public static Task <ExecutionResult> ExecuteQueryAsync <TObjectGraphType>(
            string query,
            IDictionary <string, object> userContext = null,
            object source = null)
            where TObjectGraphType : IObjectGraphType, new()
        {
            var documentExecutor = new DocumentExecuter();

            return(documentExecutor.ExecuteAsync(new ExecutionOptions
            {
                Query = query,
                Schema = new Schema
                {
                    Query = new TObjectGraphType(),
                },
                UserContext = userContext,
                Root = source,
            }));
        }
Beispiel #10
0
    public async Task Uses_ExecutionStrategySelector()
    {
        var queryStrategy    = new TestQueryExecutionStrategy();
        var mutationStrategy = new TestMutationExecutionStrategy();
        var selector         = new DefaultExecutionStrategySelector(
            new[]
        {
            new ExecutionStrategyRegistration(queryStrategy, GraphQLParser.AST.OperationType.Query),
            new ExecutionStrategyRegistration(mutationStrategy, GraphQLParser.AST.OperationType.Mutation),
        });
        var executer = new DocumentExecuter(
            new GraphQLDocumentBuilder(),
            new DocumentValidator(),
            new ComplexityAnalyzer(),
            DefaultDocumentCache.Instance,
            new IConfigureExecutionOptions[] { },
            selector);
        var schema    = new Schema();
        var graphType = new AutoRegisteringObjectGraphType <SampleGraph>();

        schema.Query    = graphType;
        schema.Mutation = graphType;
        schema.Initialize();
        var ret = await executer.ExecuteAsync(new ExecutionOptions()
        {
            Schema = schema,
            Query  = "{hero}",
            Root   = new SampleGraph(),
        }).ConfigureAwait(false);

        ret.Errors.ShouldBeNull();
        queryStrategy.Executed.ShouldBeTrue();
        ret = await executer.ExecuteAsync(new ExecutionOptions()
        {
            Schema = schema,
            Query  = "mutation{hero}",
            Root   = new SampleGraph(),
        }).ConfigureAwait(false);

        ret.Errors.ShouldBeNull();
        mutationStrategy.Executed.ShouldBeTrue();
    }
Beispiel #11
0
    public void GlobalSetup()
    {
        var services = new ServiceCollection();

        services.AddSingleton <StarWarsData>();
        services.AddSingleton <StarWarsQuery>();
        services.AddSingleton <StarWarsMutation>();
        services.AddSingleton <HumanType>();
        services.AddSingleton <HumanInputType>();
        services.AddSingleton <DroidType>();
        services.AddSingleton <CharacterInterface>();
        services.AddSingleton <EpisodeEnum>();
        services.AddSingleton <ISchema, StarWarsSchema>();

        _provider = services.BuildServiceProvider();
        _schema   = _provider.GetRequiredService <ISchema>();
        _schema.Initialize();
        _executer       = new DocumentExecuter();
        _cachedExecuter = new DocumentExecuter(new GraphQLDocumentBuilder(), new DocumentValidator(), new ComplexityAnalyzer(), new MemoryDocumentCache());
    }
    public static async Task <string> ExecuteQuery(string queryString, Inputs?inputs, ValidatorTypeCache cache)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

        queryString      = queryString.Replace("'", "\"");
        using var schema = new Schema();
        var documentExecuter = new DocumentExecuter();

        var executionOptions = new ExecutionOptions
        {
            Schema = schema,
            Query  = queryString,
            Inputs = inputs
        }
        .UseFluentValidation(cache);

        var result = await documentExecuter.ExecuteAsync(executionOptions);

        return(await new DocumentWriter(indent: true).WriteToStringAsync(result));
    }
Beispiel #13
0
 public async Task test_parallel()
 {
     Num = 0;
     CancellationTokenSource = new CancellationTokenSource();
     var de = new DocumentExecuter();
     try
     {
         _ = await de.ExecuteAsync(new ExecutionOptions
         {
             Query = "{a b}",
             Schema = new MySchema(),
             Root = this,
             CancellationToken = CancellationTokenSource.Token,
         });
     }
     catch (OperationCanceledException)
     {
     }
     Num.ShouldBe(1);
 }
        public async Task <IActionResult> Post([FromBody] GraphQLQuery query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var executionOptions = new ExecutionOptions
            {
                Schema           = Schema,
                Query            = query.Query,
                Inputs           = query.Variables.ToInputs(),
                ExposeExceptions = true,
                ValidationRules  = DocumentValidator.CoreRules().Concat(ValidationRules)
            };

            var result = await DocumentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);

            return(Ok(result));
        }
Beispiel #15
0
        public IHttpActionResult Post([FromBody] GraphQLQuery query)
        {
            var schema = new Schema
            {
                Query = new StarWarsQuery(new StarWarsContext())
            };

            var result = new DocumentExecuter().ExecuteAsync(_ =>
            {
                _.Schema = schema;
                _.Query  = query.Query;
            }).Result;

            if (result.Errors?.Count > 0)
            {
                var errors = String.Join(Environment.NewLine, result.Errors.Select(x => x.Message));
                return(BadRequest(errors));
            }

            return(Ok(result));
        }
        public static async Task <ExecutionResult> ExecuteWithErrorCheck(this DocumentExecuter documentExecuter, ExecutionOptions executionOptions)
        {
            Guard.AgainstNull(nameof(documentExecuter), documentExecuter);
            Guard.AgainstNull(nameof(executionOptions), executionOptions);
            var executionResult = await documentExecuter.ExecuteAsync(executionOptions)
                                  .ConfigureAwait(false);

            var errors = executionResult.Errors;

            if (errors != null && errors.Count > 0)
            {
                if (errors.Count == 1)
                {
                    throw errors.First();
                }

                throw new AggregateException(errors);
            }

            return(executionResult);
        }
Beispiel #17
0
        public async Task schema_first_generate_exception_with_normal_stack_trace_for_property()
        {
            var schema = Schema.For(@"
                type Query {
                    method: String!
                    property: Int!
                }
                ", builder => builder.Types.Include <Query>());

            var executor = new DocumentExecuter();
            var result   = await executor.ExecuteAsync(options =>
            {
                options.Schema = schema;
                options.Query  = "{ property }";
            }).ConfigureAwait(false);

            result.Errors.Count.ShouldBe(1);
            result.Errors[0].Code.ShouldBe("DIVIDE_BY_ZERO");
            result.Errors[0].Message.ShouldBe("Error trying to resolve field 'property'.");
            result.Errors[0].InnerException.ShouldBeOfType <DivideByZeroException>().StackTrace.ShouldStartWith("   at GraphQL.Tests.Utilities.SchemaBuilderExecutionTests.Query.get_Property()");
        }
Beispiel #18
0
        public static void QuerySuccess(GraphQL.Types.Schema schema, string query, string expected, string variables = null, bool compareBoth = true)
        {
            var exec    = new DocumentExecuter(new GraphQLDocumentBuilder(), new DocumentValidator(), new ComplexityAnalyzer());
            var result  = exec.ExecuteAsync(schema, null, query, null, variables?.ToInputs()).Result;
            var result2 = DocumentOperations.ExecuteOperationsAsync(schema, null, query, variables?.ToInputs()).Result;

            var writtenResult  = JsonConvert.SerializeObject(result.Data);
            var writtenResult2 = JsonConvert.SerializeObject(result2.Data);
            var queryResult    = CreateQueryResult(expected);
            var expectedResult = JsonConvert.SerializeObject(queryResult.Data);

            var errors  = result.Errors?.FirstOrDefault();
            var errors2 = result2.Errors?.FirstOrDefault();
            //for easy debugging
            var allTypes = schema.AllTypes;

            Assert.Null(errors?.Message);
            Assert.Null(errors2?.Message);
            Assert.Equal(expectedResult, writtenResult);
            Assert.Equal(expectedResult, writtenResult2);
        }
    public async Task DocumentExecuter_really_big_double_Invalid()
    {
        var de = new DocumentExecuter();

        _maxNumber.ShouldBe("1797693134862320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0");
        var valid = await de.ExecuteAsync(new ExecutionOptions
        {
            // create a floating-point value that is larger than double.MaxValue
            // in the expression "{double.MaxValue:0}0.0" below, the 0.0 effectively
            // multiplies double.MaxValue by 10 and the .0 forces the parser to
            // assume it is a floating point value rather than a large integer
            Query  = $"{{ test(arg:{_maxNumber}) }}",
            Schema = Schema,
        }).ConfigureAwait(false);

        valid.ShouldNotBeNull();
        valid.Data.ShouldBeNull();
        valid.Errors.ShouldNotBeNull();
        valid.Errors.Count.ShouldBe(1);
        valid.Errors[0].Message.ShouldBe($"Argument 'arg' has invalid value. Expected type 'Float', found {_maxNumber}.");
    }
Beispiel #20
0
        public static Task <ExecutionResult> ExecuteQueryAsync <TObjectGraphType>(
            IServiceProvider serviceProvider,
            string query,
            IDictionary <string, object>?userContext = null,
            object?source = null)
            where TObjectGraphType : IObjectGraphType
        {
            var graphType        = (IObjectGraphType)serviceProvider.GetService(typeof(TObjectGraphType));
            var documentExecutor = new DocumentExecuter();

            return(documentExecutor.ExecuteAsync(new ExecutionOptions
            {
                Query = query,
                Schema = new Schema
                {
                    Query = graphType,
                },
                UserContext = userContext,
                Root = source,
            }));
        }
Beispiel #21
0
        public async Task DocumentExecuter_has_valid_options()
        {
            var de    = new DocumentExecuter();
            var valid = await de.ExecuteAsync(new ExecutionOptions
            {
                Query  = "{test}",
                Schema = Schema,
            });

            await Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                await de.ExecuteAsync(new ExecutionOptions()
                {
                    Query  = null,
                    Schema = Schema,
                });
            });

            await Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                await de.ExecuteAsync(new ExecutionOptions()
                {
                    Query  = "{test}",
                    Schema = null,
                });
            });

            await Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                await de.ExecuteAsync(new ExecutionOptions()
                {
                    Query           = "{test}",
                    Schema          = Schema,
                    FieldMiddleware = null,
                });
            });
        }
    public async Task schema_first_generate_exception_with_normal_stack_trace_for_method()
    {
        var schema = Schema.For(@"
                type Query {
                    method: String!
                    property: Int!
                }
                ", builder => builder.Types.Include <Query>());

        var executor = new DocumentExecuter();
        var result   = await executor.ExecuteAsync(options =>
        {
            options.Schema = schema;
            options.Query  = "{ method }";
        }).ConfigureAwait(false);

        result.Errors.Count.ShouldBe(1);
        result.Errors[0].Code.ShouldBe("OVERFLOW");
        result.Errors[0].Message.ShouldBe("Error trying to resolve field 'method'.");

        var stack = result.Errors[0].InnerException.ShouldBeOfType <OverflowException>().StackTrace;

        if (stack.StartsWith("   в "))
        {
            stack = stack.Remove(0, 5);
        }
        if (stack.StartsWith("   at "))
        {
            stack = stack.Remove(0, 6);
        }
        if (stack.StartsWith("   在 "))
        {
            stack = stack.Remove(0, 5);
        }

        stack.ShouldStartWith("GraphQL.Tests.Utilities.SchemaBuilderExecutionTests.Query.Method()");
    }
Beispiel #23
0
        static void Main(string[] args)
        {
            /*
             * Schema schema = new Schema { Query = new RootQueries() };
             * string resultJson = schema.Execute(_ =>
             * {
             *    _.Query = "{queryPerson{id name age}}";
             *    _.FieldMiddleware.Use(next =>
             *    {
             *        return context =>{
             *            return new MyMiddleWare().Invock(context, next);
             *        };
             *
             *    });
             * });
             * Console.WriteLine(resultJson);
             * Console.ReadKey();
             */
            Schema schema = new Schema {
                Query = new RootQueries()
            };
            var             start    = DateTime.UtcNow;
            var             executor = new DocumentExecuter();
            ExecutionResult result   = executor.ExecuteAsync(_ =>
            {
                _.Schema        = schema;
                _.Query         = "query{queryPerson{id name age}}";
                _.EnableMetrics = true;
                _.FieldMiddleware.Use <MyMiddleWare>();
            }).Result;

            result.EnrichWithApolloTracing(start);
            string serialStr = Newtonsoft.Json.JsonConvert.SerializeObject(result);

            Console.WriteLine(serialStr);
            Console.ReadKey();
        }
        public async Task GraphQLFieldQuery_Test()
        {
            var root         = new RootQuery();
            var mutation     = new RootMutation();
            var schema       = new GraphQLRootSchema(root, mutation);
            var queryBuilder = new BasicQueryBuilder();
            var executor     = new DocumentExecuter();


            schema.Register(queryBuilder);
            Assert.True(schema.Query.HasField("defaultTest"));

            var result = await executor.ExecuteAsync(new ExecutionOptions()
            {
                Schema        = schema,
                Query         = "query TestQuery { defaultTest(returnOne: 5, returnTwo: 5) }",
                OperationName = "TestQuery"
            }).ConfigureAwait(false);


            Assert.NotNull(result);
            Assert.NotNull(result?.Data);
            Assert.Equal(10, ((Dictionary <string, object>)result?.Data)["defaultTest"]);
        }
Beispiel #25
0
        public GraphQLTestBase(ITestOutputHelper output)
        {
            Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger();

            _output = output;

            var store      = new DefaultStore(null);
            var stateStore = new TrieStateStore(
                new DefaultKeyValueStore(null),
                new DefaultKeyValueStore(null)
                );
            var genesisBlock = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock(blockAction : new RewardGold());

            var blockPolicy = new BlockPolicy <PolymorphicAction <ActionBase> >(blockAction: new RewardGold());
            var blockChain  = new BlockChain <PolymorphicAction <ActionBase> >(
                blockPolicy,
                store,
                stateStore,
                genesisBlock,
                renderers: new IRenderer <PolymorphicAction <ActionBase> >[] { new BlockRenderer(), new ActionRenderer() }
                );

            var tempKeyStorePath = Path.Join(Path.GetTempPath(), Path.GetRandomFileName());
            var keyStore         = new Web3KeyStore(tempKeyStorePath);

            StandaloneContextFx = new StandaloneContext
            {
                BlockChain = blockChain,
                KeyStore   = keyStore,
            };

            Schema = new StandaloneSchema(new TestServiceProvider(StandaloneContextFx));
            Schema.Subscription.As <StandaloneSubscription>().RegisterTipChangedSubscription();

            DocumentExecutor = new DocumentExecuter();
        }
        private static void RunQuery()
        {
            var query = @" {
                droids {
                    droidId
                    name
                    primaryFunction
                    appearsIn
                    friends {
                        name
                        ... on Human {
                            humanId
                            appearsIn
                        }
                    }
                }
            }";

            var    executer = new DocumentExecuter();
            var    writer = new DocumentWriter(true);
            string output1, output2;

            // Example 1 - QueryRoot.
            using (var root = new QueryRoot())
                using (var schema = new Schema <QueryRoot>())
                {
                    var result = executer.ExecuteAsync(schema, root, query, null).Result;
                    output1 = writer.Write(result);
                    Console.WriteLine("Example 1 output (QueryRoot):");
                    Console.WriteLine("-----------------------------");
                    Console.WriteLine(output1);
                    Console.WriteLine();
                }

            // Example 2 - DbContext.
            // I get the feeling there are reasons why wouldn't
            // want to do this but for simple scenarios it seems to suffice.
            using (var db = new StarWarsContext())
                using (var schema = new Schema <StarWarsContext>())
                {
                    var result = executer.ExecuteAsync(schema, db, query, null).Result;
                    output2 = writer.Write(result);
                    Console.WriteLine("Example 2 output (StarWarsContext):");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine(output2);
                    Console.WriteLine();
                }

            // Confirm we got the same result, just 'cause...
            var defaultColor = Console.ForegroundColor;

            if (output1 == output2)
            {
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("✓ Outputs are the same");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.WriteLine("× Outputs are different");
            }
            Console.ForegroundColor = defaultColor;
        }
        public async Task VerifyCorrectExecutionOrder()
        {
            var sb = new StringBuilder();
            Func <IResolveFieldContext, object> resolver = context =>
            {
                sb.AppendLine(string.Join(".", context.ResponsePath));
                return("test");
            };
            var leaderGraphType = new ObjectGraphType()
            {
                Name = "LoaderType"
            };

            leaderGraphType.Field <StringGraphType>("lastName", resolve: resolver);
            leaderGraphType.Field <StringGraphType>("name", resolve: resolver);
            var familiesGraphType = new ObjectGraphType()
            {
                Name = "FamiliesType"
            };

            familiesGraphType.Field("leader", leaderGraphType, resolve: resolver);
            familiesGraphType.Field("leader_dataLoader", leaderGraphType, resolve: context =>
            {
                resolver(context);
                return(new SimpleDataLoader <object>(ctx =>
                {
                    sb.AppendLine(string.Join(".", context.ResponsePath) + "-completed");
                    return Task.FromResult <object>("test");
                }));
            });
            var queryGraphType = new ObjectGraphType();

            queryGraphType.Field("families", new ListGraphType(familiesGraphType), resolve: context =>
            {
                resolver(context);
                return(new object[] { "a", "a", "a" });
            });
            var schema = new Schema
            {
                Query    = queryGraphType,
                Mutation = queryGraphType,
            };
            var documentExecuter = new DocumentExecuter();
            var executionOptions = new ExecutionOptions()
            {
                Schema = schema,
                Query  = "mutation { families { leader_dataLoader { lastName name } leader { lastName name } } }",
            };
            await documentExecuter.ExecuteAsync(executionOptions);

            sb.ToString().ShouldBeCrossPlat(@"families
families.0.leader_dataLoader
families.0.leader
families.0.leader.lastName
families.0.leader.name
families.1.leader_dataLoader
families.1.leader
families.1.leader.lastName
families.1.leader.name
families.2.leader_dataLoader
families.2.leader
families.2.leader.lastName
families.2.leader.name
families.0.leader_dataLoader-completed
families.1.leader_dataLoader-completed
families.2.leader_dataLoader-completed
families.0.leader_dataLoader.lastName
families.0.leader_dataLoader.name
families.1.leader_dataLoader.lastName
families.1.leader_dataLoader.name
families.2.leader_dataLoader.lastName
families.2.leader_dataLoader.name
");
        }
 public QueryGraphTypeTests()
 {
     Schema     = new SimpleSchema();
     Executer   = new DocumentExecuter();
     Serializer = new GraphQLSerializer();
 }
 public BaseGraphQLController(ISchema schema, DocumentExecuter documentExecuter, ILogger <BaseGraphQLController> logger)
 {
     _schema           = schema;
     _documentExecuter = documentExecuter;
     _logger           = logger;
 }
Beispiel #30
0
 public ApiController(IContainer container)
 {
     Container = container;
     Executer  = new DocumentExecuter();
     Schema    = Container.GetInstance <ApiSchema>();
 }
        public async Task Invoke(HttpContext httpContext)
        {
            var logger = httpContext.RequestServices.GetService <ILogger <GraphQlMiddleware> >();

            HttpRequest  request  = httpContext.Request;
            HttpResponse response = httpContext.Response;

            // GraphQL HTTP only supports GET and POST methods.
            if (request.Method != "GET" && request.Method != "POST")
            {
                response.Headers.Add("Allow", "GET, POST");
                response.StatusCode = 405;

                return;
            }

            // Check authorization
            if (_options.AuthorizationPolicy != null)
            {
                var authorizationService = httpContext.RequestServices.GetRequiredService <IAuthorizationService>();
                var authzResult          = await authorizationService.AuthorizeAsync(httpContext.User, _options.AuthorizationPolicy);

                if (!authzResult.Succeeded)
                {
                    await httpContext.ForbidAsync();

                    return;
                }
            }

            GraphQlParameters parameters = await GetParametersAsync(request);

            ISchema schema = _schemaProvider.Create(httpContext.RequestServices);

            var executer = new DocumentExecuter();

            var result = await executer.ExecuteAsync(options =>
            {
                options.Schema                  = schema;
                options.Query                   = parameters.Query;
                options.OperationName           = parameters.OperationName;
                options.Inputs                  = parameters.GetInputs();
                options.CancellationToken       = httpContext.RequestAborted;
                options.ComplexityConfiguration = _options.ComplexityConfiguration;
                options.UserContext             = httpContext;
                options.ExposeExceptions        = _options.ExposeExceptions;
            });

            if (result.Errors?.Count > 0)
            {
                logger.LogError("GraphQL Result {Errors}", result.Errors);
            }

            var writer = new DocumentWriter(indent: _options.FormatOutput);
            var json   = writer.Write(result);

            response.StatusCode  = 200;
            response.ContentType = "application/json; charset=utf-8";

            await response.WriteAsync(json);
        }
Beispiel #32
0
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            if (context.WebSockets.IsWebSocketRequest)
            {
                await next(context);

                return;
            }

            // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/
            var httpRequest    = context.Request;
            var gqlRequest     = new GraphQLRequest();
            var documentWriter = new DocumentWriter(_schema.GetJsonSerializerSettings());

            if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(GraphQLRequest.QueryKey)))
            {
                ExtractGraphQLRequestFromQueryString(httpRequest.Query, gqlRequest);
            }
            else if (HttpMethods.IsPost(httpRequest.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader))
                {
                    await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed.");

                    return;
                }

                switch (mediaTypeHeader.MediaType)
                {
                case JsonContentType:
                    gqlRequest = Deserialize <GraphQLRequest>(httpRequest.Body);
                    break;

                case GraphQLContentType:
                    gqlRequest.Query = await ReadAsStringAsync(httpRequest.Body);

                    break;

                case FormUrlEncodedContentType:
                    var formCollection = await httpRequest.ReadFormAsync();

                    ExtractGraphQLRequestFromPostBody(formCollection, gqlRequest);
                    break;

                default:
                    await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: non-supported media type. Must be of '{JsonContentType}', '{GraphQLContentType}', or '{FormUrlEncodedContentType}'. See: http://graphql.org/learn/serving-over-http/.");

                    return;
                }
            }

            IEnumerable <IValidationRule> validationRules;

            try
            {
                validationRules = _container.GetAllInstances <IValidationRule>();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
                validationRules = new IValidationRule[0];
            }

            var executer = new DocumentExecuter();
            var result   = await executer.ExecuteAsync(x =>
            {
                x.Schema                  = _schema;
                x.OperationName           = gqlRequest.OperationName;
                x.Query                   = gqlRequest.Query;
                x.Inputs                  = gqlRequest.GetInputs();
                x.UserContext             = _userContextBuilder.BuildContext();
                x.ValidationRules         = validationRules.Concat(DocumentValidator.CoreRules);
                x.CancellationToken       = context.RequestAborted;
                x.ComplexityConfiguration = _complexityConfigurationFactory.GetComplexityConfiguration();
            });

            if (result.Errors?.Any(x => x.Code == "auth-required") == true && context.Response.Headers.ContainsKey("Token-Expired"))
            {
                await WriteUnauthorizedResponseAsync(context, documentWriter, result);
            }
            else
            {
                await WriteResponseAsync(context, documentWriter, result);
            }
        }
Beispiel #33
0
 public ApiController(IContainer container)
 {
     Container = container;
     Executer  = new DocumentExecuter();
     Schema    = new ApiSchema(container, Assembly.GetExecutingAssembly());
 }
Beispiel #34
0
        /// <summary>
        ///     Execute all operations async.
        /// </summary>
        /// <returns>Aggregated results.</returns>
        public static async Task <ExecutionResult> ExecuteOperationsAsync(
            ISchema schema,
            object root,
            string query,
            Inputs inputs = null,
            CancellationToken cancellationToken = default(CancellationToken),
            IEnumerable <IValidationRule> rules = null,
            bool validate = true,
            IDocumentBuilder documentBuilder = null,
            int?maxOperationNodes            = null,
            int?maxTasksAllowed = null
            )
        {
            var savedDocument = new SavedDocumentBuilder(query, documentBuilder);

            if (savedDocument.OperationNodes > maxOperationNodes)
            {
                throw new InvalidOperationException($"Graph query contains more than the allowed operation limit ({maxOperationNodes}) for one request.");
            }

            if (savedDocument.Document.Operations == null || savedDocument.Document.Operations.Count() <= 1)
            {
                //run the typical way.
                var defaultBuilder = new DocumentExecuter(savedDocument, DocumentValidator, ComplexityAnalyzerInstance, maxTasksAllowed);

                return
                    (await
                     defaultBuilder.ExecuteAsync(
                         new ExecutionOptions
                {
                    Schema = schema,
                    Root = root,
                    Query = query,
                    Inputs = inputs,
                    CancellationToken = cancellationToken,
                    ValidationRules = rules,
                    EnableDocumentValidation = validate,
                    EnableMetrics = false,
                    SetFieldMiddleware = false
                }));
            }

            var result = new ExecutionResult();
            var nonValidatedExecutionar =
                new DocumentExecuter(savedDocument, DocumentValidator, ComplexityAnalyzerInstance, maxTasksAllowed);
            var aggregateData = new Dictionary <string, object>();

            try
            {
                if (validate)
                {
                    var validationResult = DocumentValidator.Validate(query, schema, savedDocument.Document, rules);

                    if (!validationResult.IsValid)
                    {
                        result.Data   = aggregateData;
                        result.Errors = validationResult.Errors;

                        return(result);
                    }
                }

                foreach (var operation in savedDocument.Document.Operations)
                {
                    var opResult =
                        await nonValidatedExecutionar.ExecuteAsync(new ExecutionOptions
                    {
                        Schema                   = schema,
                        Root                     = root,
                        Query                    = query,
                        Inputs                   = inputs,
                        CancellationToken        = cancellationToken,
                        ValidationRules          = rules,
                        OperationName            = operation.Name,
                        EnableDocumentValidation = false,
                        EnableMetrics            = false,
                        SetFieldMiddleware       = false
                    });

                    if (opResult.Errors != null && opResult.Errors.Any())
                    {
                        return(opResult);
                    }

                    aggregateData.Add(operation.Name, opResult.Data);
                }
            }
            catch (Exception exc)
            {
                if (result.Errors == null)
                {
                    result.Errors = new ExecutionErrors();
                }

                result.Data = null;
                result.Errors.Add(new ExecutionError(exc.Message, exc));
                return(result);
            }

            result.Data = aggregateData;

            return(result);
        }
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            if (context.WebSockets.IsWebSocketRequest || !context.Request.Path.StartsWithSegments(_path))
            {
                await next(context);

                return;
            }

            // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/
            var httpRequest    = context.Request;
            var gqlRequest     = new GraphQLRequest();
            var documentWriter = new DocumentWriter(Formatting.Indented, _schema.GetJsonSerializerSettings());

            if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(GraphQLRequest.QueryKey)))
            {
                ExtractGraphQLRequestFromQueryString(httpRequest.Query, gqlRequest);
            }
            else if (HttpMethods.IsPost(httpRequest.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader))
                {
                    await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed.");

                    return;
                }

                switch (mediaTypeHeader.MediaType)
                {
                case JsonContentType:
                    gqlRequest = Deserialize <GraphQLRequest>(httpRequest.Body);
                    break;

                case GraphQLContentType:
                    gqlRequest.Query = await ReadAsStringAsync(httpRequest.Body);

                    break;

                case FormUrlEncodedContentType:
                    var formCollection = await httpRequest.ReadFormAsync();

                    ExtractGraphQLRequestFromPostBody(formCollection, gqlRequest);
                    break;

                default:
                    await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: non-supported media type. Must be of '{JsonContentType}', '{GraphQLContentType}', or '{FormUrlEncodedContentType}'. See: http://graphql.org/learn/serving-over-http/.");

                    return;
                }
            }

            var executer = new DocumentExecuter();
            var result   = await executer.ExecuteAsync(x =>
            {
                x.Schema                  = _schema;
                x.OperationName           = gqlRequest.OperationName;
                x.Query                   = gqlRequest.Query;
                x.Inputs                  = gqlRequest.GetInputs();
                x.UserContext             = _userContextBuilder.BuildContext();
                x.ValidationRules         = new[] { new AuthenticationValidationRule() }.Concat(DocumentValidator.CoreRules);
                x.CancellationToken       = context.RequestAborted;
                x.ComplexityConfiguration = _complexityConfigurationFactory.GetComplexityConfiguration();
            });

            if (result.Errors != null)
            {
                _logger.LogError("GraphQL execution error(s): {Errors}", result.Errors);
            }

            await WriteResponseAsync(context, documentWriter, result);
        }
Beispiel #36
0
        /// <summary>
        /// Check the schema against introspection query
        /// </summary>
        /// <param name="schema">The schema</param>
        /// <returns>List of errors</returns>
        public static IEnumerable <string> CheckSchemaIntrospection(Schema schema)
        {
            var result = new DocumentExecuter().ExecuteAsync(
                r =>
            {
                r.Schema      = schema;
                r.Query       = Queries.IntrospectionQuery;
                r.UserContext = new RequestContext();
            }).Result;
            var response = new DocumentWriter(true).Write(result);
            var json     = JObject.Parse(response);
            var types    =
                (json.SelectToken("data.__schema.types") as JArray)?.ToDictionary(
                    p => ((JObject)p).Property("name")?.Value,
                    p => (JObject)p);

            if (types == null)
            {
                yield return("Could not get types list via introspection");

                yield break;
            }

            var inputTypesChecked = new List <string>();

            foreach (var type in types.Values.Where(t => !t.Property("name").Value.ToObject <string>().StartsWith("__")))
            {
                var typeName = type.Property("name").Value.ToObject <string>();
                var fields   = type.Property("fields")?.Value as JArray;
                if (fields != null)
                {
                    foreach (var field in fields)
                    {
                        var fieldType = field.SelectToken("type.kind")?.ToObject <string>() == "LIST"
                                            ? field.SelectToken("type.ofType.name")?.ToObject <string>()
                                            : field.SelectToken("type.name")?.ToObject <string>();
                        var fieldName = field.SelectToken("name")?.ToObject <string>();
                        if (!types.ContainsKey(fieldType ?? string.Empty))
                        {
                            yield return($"{typeName} property {fieldName} has unknown type {fieldType}");
                        }

                        var arguments = field.SelectToken("args") as JArray;
                        if (arguments == null || arguments.Count == 0)
                        {
                            continue;
                        }

                        foreach (var argument in arguments)
                        {
                            var argumentType = argument.SelectToken("type.kind")?.ToObject <string>() == "LIST"
                                                   ? argument.SelectToken("type.ofType.name")?.ToObject <string>()
                                                   : argument.SelectToken("type.name")?.ToObject <string>();
                            var argumentName = argument.SelectToken("name")?.ToObject <string>();

                            JObject argumentTypeJson;
                            if (!types.TryGetValue(argumentType ?? string.Empty, out argumentTypeJson))
                            {
                                yield return
                                    ($"{typeName} property {fieldName} "
                                     + $"has argument {argumentName} of unknown type {argumentType}");
                            }
                            else
                            {
                                var argumentTypeKind = argumentTypeJson.SelectToken("kind").ToObject <string>();
                                if (argumentTypeKind != "SCALAR" && argumentTypeKind != "ENUM" &&
                                    argumentTypeKind != "INPUT_OBJECT")
                                {
                                    yield return
                                        ($"{typeName} property {fieldName} "
                                         + $"has argument {argumentName} of type {argumentType} "
                                         + $"of unsupported kind {argumentTypeKind}");
                                }
                                else if (argumentTypeKind == "INPUT_OBJECT")
                                {
                                    foreach (
                                        var error in
                                        CheckIntrospectionInputType(argumentTypeJson, types, inputTypesChecked))
                                    {
                                        yield return(error);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }