Beispiel #1
0
        public void SupportsDefaultArgumentsInNonRoot()
        {
            var schemaProvider = SchemaBuilder.FromObject <TestSchema>();

            schemaProvider.AddEnum("HeightUnit", typeof(HeightUnit), "Unit of height measurement");
            schemaProvider.Type <Person>().ReplaceField("height", new { unit = HeightUnit.Cm }, (p, param) => p.GetHeight(param.unit), "Return me, or someone else");
            var result = new GraphQLCompiler(schemaProvider, new DefaultMethodProvider()).Compile(@"query {
                people { id height }
            }").ExecuteQuery(new TestSchema(), null);

            Assert.Equal(1, Enumerable.Count(result.Data));
            var person = Enumerable.First((dynamic)result.Data["people"]);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("id", person.GetType().GetFields()[0].Name);
            Assert.Equal("height", person.GetType().GetFields()[1].Name);
            Assert.Equal(183.0, person.height);
        }
Beispiel #2
0
        public void CanParseSimpleQueryOptionalComma()
        {
            var objectSchemaProvider = SchemaBuilder.FromObject <TestSchema>();
            var tree = new GraphQLCompiler(objectSchemaProvider, new DefaultMethodProvider()).Compile(@"
{
	people { id, name }
}");

            Assert.Single(tree.Fields);
            dynamic result = tree.Fields.ElementAt(0).Execute(new TestSchema());

            Assert.Equal(1, Enumerable.Count(result));
            var person = Enumerable.ElementAt(result, 0);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("Id", person.GetType().GetFields()[0].Name);
            Assert.Equal("Name", person.GetType().GetFields()[1].Name);
        }
        public void SupportsArguments()
        {
            var schemaProvider = SchemaBuilder.FromObject <TestSchema>(false);

            // Add a argument field with a require parameter
            schemaProvider.AddField("user", new { id = Required <int>() }, (ctx, param) => ctx.Users.Where(u => u.Id == param.id).FirstOrDefault(), "Return a user by ID");
            var tree = new GraphQLCompiler(schemaProvider, new DefaultMethodProvider()).Compile(@"query {
	user(id: 1) { id }
}").Operations.First();

            // db => db.Users.Where(u => u.Id == id).Select(u => new {id = u.Id}]).FirstOrDefault()
            Assert.Single(tree.Fields);
            dynamic user = tree.Fields.ElementAt(0).Execute(new TestSchema());

            // we only have the fields requested
            Assert.Equal(1, user.GetType().GetFields().Length);
            Assert.Equal("id", user.GetType().GetFields()[0].Name);
            Assert.Equal(1, user.id);
        }
        public void CanParseSimpleQuery()
        {
            var objectSchemaProvider = SchemaBuilder.FromObject <TestSchema>();
            var tree = new GraphQLCompiler(objectSchemaProvider, new DefaultMethodProvider()).Compile(@"
{
	people { id name }
}");

            Assert.Single(tree.Operations);
            Assert.Single(tree.Operations.First().Fields);
            var result = tree.ExecuteQuery(new TestSchema());

            Assert.Single(result.Data);
            var person = Enumerable.ElementAt((dynamic)result.Data["people"], 0);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("id", person.GetType().GetFields()[0].Name);
            Assert.Equal("name", person.GetType().GetFields()[1].Name);
        }
Beispiel #5
0
        public void CanParseQueryWithCollectionDeep()
        {
            var tree = new GraphQLCompiler(SchemaBuilder.FromObject <TestSchema>(), new DefaultMethodProvider()).Compile(@"
{
	people { id
		projects {
			name
			tasks { id name }
		}
	}
}");

            Assert.Single(tree.Fields);
            dynamic result = tree.Fields.ElementAt(0).Execute(new TestSchema());

            Assert.Equal(1, Enumerable.Count(result));
            var person = Enumerable.ElementAt(result, 0);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("Id", person.GetType().GetFields()[0].Name);
            // make sure we sub-select correctly to make the requested object graph
            Assert.Equal("projects", person.GetType().GetFields()[1].Name);
            var projects = person.projects;

            Assert.Equal(1, Enumerable.Count(projects));
            var project = Enumerable.ElementAt(projects, 0);

            Assert.Equal(2, project.GetType().GetFields().Length);
            Assert.Equal("Name", project.GetType().GetFields()[0].Name);
            Assert.Equal("tasks", project.GetType().GetFields()[1].Name);

            var tasks = project.tasks;

            Assert.Equal(1, Enumerable.Count(tasks));
            var task = Enumerable.ElementAt(tasks, 0);

            Assert.Equal(2, task.GetType().GetFields().Length);
            Assert.Equal("Id", task.GetType().GetFields()[0].Name);
            Assert.Equal("Name", task.GetType().GetFields()[1].Name);
        }
        public void SupportsComments()
        {
            var schemaProvider = SchemaBuilder.FromObject <TestSchema>();
            // Add a argument field with a require parameter
            var tree = new GraphQLCompiler(schemaProvider, new DefaultMethodProvider()).Compile(@"
            # hey there
            query {
                # yep
                person(id: ""cccccccc-bbbb-4444-1111-ccddeeff0033"") { # this is a good field
                    id projects { id name }
                }
            }").Operations.First();

            Assert.Single(tree.Fields);
            dynamic user = tree.Fields.ElementAt(0).Execute(new TestSchema());

            // we only have the fields requested
            Assert.Equal(2, user.GetType().GetFields().Length);
            Assert.Equal("id", user.GetType().GetFields()[0].Name);
            Assert.Equal(new Guid("cccccccc-bbbb-4444-1111-ccddeeff0033"), user.id);
        }
Beispiel #7
0
        public void SupportsDefaultArgumentsInNonRoot()
        {
            var schemaProvider = SchemaBuilder.FromObject <TestSchema>();

            schemaProvider.Type <Person>().ReplaceField("height", new { unit = HeightUnit.Cm }, (p, param) => p.GetHeight(param.unit), "Return me, or someone else");
            var tree = new GraphQLCompiler(schemaProvider, new DefaultMethodProvider()).Compile(@"query {
                people { id height }
            }");

            Assert.Single(tree.Fields);
            dynamic result = tree.Fields.ElementAt(0).Execute(new TestSchema());

            Assert.Equal(1, Enumerable.Count(result));
            var person = Enumerable.First(result);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("Id", person.GetType().GetFields()[0].Name);
            Assert.Equal("Height", person.GetType().GetFields()[1].Name);
            Assert.Equal(183.0, person.Height);
        }
Beispiel #8
0
        public void CanQueryExtendedFields()
        {
            var objectSchemaProvider = SchemaBuilder.FromObject <TestSchema>();

            objectSchemaProvider.Type <Person>().AddField("thing", p => p.Id + " - " + p.Name, "A weird field I want");
            var tree = new GraphQLCompiler(objectSchemaProvider, new DefaultMethodProvider()).Compile(@"
{
	people { id thing }
}");

            Assert.Single(tree.Fields);
            dynamic result = tree.Fields.ElementAt(0).Execute(new TestSchema());

            Assert.Equal(1, Enumerable.Count(result));
            var person = Enumerable.ElementAt(result, 0);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("Id", person.GetType().GetFields()[0].Name);
            Assert.Equal("thing", person.GetType().GetFields()[1].Name);
        }
        public void CanQueryExtendedFields()
        {
            var objectSchemaProvider = SchemaBuilder.FromObject <TestSchema>();

            objectSchemaProvider.Type <Person>().AddField("thing", p => p.Id + " - " + p.Name, "A weird field I want");
            var tree = new GraphQLCompiler(objectSchemaProvider, new DefaultMethodProvider()).Compile(@"
{
	people { id thing }
}");

            Assert.Single(tree.Operations);
            Assert.Single(tree.Operations.First().QueryFields);
            var result = tree.ExecuteQuery(new TestSchema(), null);

            Assert.Single(result.Data);
            var person = Enumerable.ElementAt((dynamic)result.Data["people"], 0);

            // we only have the fields requested
            Assert.Equal(2, person.GetType().GetFields().Length);
            Assert.Equal("id", person.GetType().GetFields()[0].Name);
            Assert.Equal("thing", person.GetType().GetFields()[1].Name);
        }
Beispiel #10
0
        /// <summary>
        /// Execute a query using this schema.
        /// </summary>
        /// <param name="gql">The query</param>
        /// <param name="context">The context object. An instance of the context the schema was build from</param>
        /// <param name="serviceProvider">A service provider used for looking up dependencies of field selections and mutations</param>
        /// <param name="claims">Optional claims to check access for queries</param>
        /// <param name="methodProvider"></param>
        /// <param name="includeDebugInfo"></param>
        /// <typeparam name="TContextType"></typeparam>
        /// <returns></returns>
        public async Task <QueryResult> ExecuteQueryAsync(QueryRequest gql, TContextType context, IServiceProvider serviceProvider, ClaimsIdentity claims, IMethodProvider methodProvider = null)
        {
            if (methodProvider == null)
            {
                methodProvider = new DefaultMethodProvider();
            }

            QueryResult result;

            try
            {
                var graphQLCompiler = new GraphQLCompiler(this, methodProvider);
                var queryResult     = graphQLCompiler.Compile(gql, claims);
                result = await queryResult.ExecuteQueryAsync(context, serviceProvider, gql.OperationName);
            }
            catch (Exception ex)
            {
                // error with the whole query
                result = new QueryResult(new GraphQLError(ex.InnerException != null ? ex.InnerException.Message : ex.Message));
            }

            return(result);
        }
        public void CanParseQueryWithRelation()
        {
            var tree = new GraphQLCompiler(SchemaBuilder.FromObject <TestSchema>(), new DefaultMethodProvider()).Compile(@"
{
	people { id name user { field1 } }
}");
            // People.Select(p => new { Id = p.Id, Name = p.Name, User = new { Field1 = p.User.Field1 })
            var result = tree.ExecuteQuery(new TestSchema());

            Assert.Equal(1, Enumerable.Count((dynamic)result.Data["people"]));
            var person = Enumerable.ElementAt((dynamic)result.Data["people"], 0);

            // we only have the fields requested
            Assert.Equal(3, person.GetType().GetFields().Length);
            Assert.Equal("id", person.GetType().GetFields()[0].Name);
            Assert.Equal("name", person.GetType().GetFields()[1].Name);
            // make sure we sub-select correctly to make the requested object graph
            Assert.Equal("user", person.GetType().GetFields()[2].Name);
            var user = person.user;

            Assert.Single(user.GetType().GetFields());
            Assert.Equal("field1", user.GetType().GetFields()[0].Name);
        }
Beispiel #12
0
        /// <summary>
        /// Execute a query using this schema.
        /// </summary>
        /// <param name="gql">The query</param>
        /// <param name="context">The context object. An instance of the context the schema was build from</param>
        /// <param name="serviceProvider">A service provider used for looking up dependencies of field selections and mutations</param>
        /// <param name="claims">Optional claims to check access for queries</param>
        /// <param name="methodProvider"></param>
        /// <param name="includeDebugInfo"></param>
        /// <typeparam name="TContextType"></typeparam>
        /// <returns></returns>
        public QueryResult ExecuteQuery(QueryRequest gql, TContextType context, IServiceProvider serviceProvider, ClaimsIdentity claims, IMethodProvider methodProvider = null, bool includeDebugInfo = false)
        {
            if (methodProvider == null)
            {
                methodProvider = new DefaultMethodProvider();
            }
            Stopwatch timer = null;

            if (includeDebugInfo)
            {
                timer = new Stopwatch();
                timer.Start();
            }

            QueryResult result;

            try
            {
                var graphQLCompiler = new GraphQLCompiler(this, methodProvider);
                var queryResult     = graphQLCompiler.Compile(gql, claims);
                result = queryResult.ExecuteQuery(context, serviceProvider, gql.OperationName);
            }
            catch (Exception ex)
            {
                // error with the whole query
                result = new QueryResult {
                    Errors = { new GraphQLError(ex.InnerException != null ? ex.InnerException.Message : ex.Message) }
                };
            }
            if (includeDebugInfo && timer != null)
            {
                timer.Stop();
                result.SetDebug(new { TotalMilliseconds = timer.ElapsedMilliseconds });
            }

            return(result);
        }
Beispiel #13
0
        /// <summary>
        /// Extension method to query an object purely based on the a defined schema of that object.
        /// </summary>
        /// <param name="context">The root of your object graph you are querying. E.g. a DbContext</param>
        /// <param name="request">GraphQL request object</param>
        /// <param name="schemaProvider">Schema definition. Defines new fields/entities. Maps names, etc.</param>
        /// <param name="methodProvider">Extend the query language with methods</param>
        /// <param name="includeDebugInfo">Include debug/timing information in the result</param>
        /// <typeparam name="TType"></typeparam>
        /// <returns></returns>
        public static QueryResult QueryObject <TType>(this TType context, QueryRequest request, ISchemaProvider schemaProvider, IMethodProvider methodProvider = null, bool includeDebugInfo = false, params object[] mutationArgs)
        {
            if (methodProvider == null)
            {
                methodProvider = new DefaultMethodProvider();
            }
            Stopwatch timer = null;

            if (includeDebugInfo)
            {
                timer = new Stopwatch();
                timer.Start();
            }

            QueryResult result = null;

            try
            {
                var graphQLCompiler = new GraphQLCompiler(schemaProvider, methodProvider);
                var queryResult     = graphQLCompiler.Compile(request);
                result = queryResult.ExecuteQuery(context, request.OperationName, mutationArgs);
            }
            catch (Exception ex)
            {
                // error with the whole query
                result = new QueryResult {
                    Errors = { new GraphQLError(ex.InnerException != null ? ex.InnerException.Message : ex.Message) }
                };
            }
            if (includeDebugInfo && timer != null)
            {
                timer.Stop();
                result.SetDebug(new { TotalMilliseconds = timer.ElapsedMilliseconds });
            }

            return(result);
        }
Beispiel #14
0
        public void CanParseQueryWithRelationDeep()
        {
            var tree = new GraphQLCompiler(SchemaBuilder.FromObject <TestSchema>(), new DefaultMethodProvider()).Compile(@"
{
	people { id name
		User {
			field1
			nestedRelation { id name }
		}
	}
}");

            // People.Select(p => new { Id = p.Id, Name = p.Name, User = new { Field1 = p.User.Field1, NestedRelation = new { Id = p.User.NestedRelation.Id, Name = p.User.NestedRelation.Name } })
            Assert.Single(tree.Fields);
            dynamic result = tree.Fields.ElementAt(0).Execute(new TestSchema());

            Assert.Equal(1, Enumerable.Count(result));
            var person = Enumerable.ElementAt(result, 0);

            // we only have the fields requested
            Assert.Equal(3, person.GetType().GetFields().Length);
            Assert.Equal("Id", person.GetType().GetFields()[0].Name);
            Assert.Equal("Name", person.GetType().GetFields()[1].Name);
            // make sure we sub-select correctly to make the requested object graph
            Assert.Equal("User", person.GetType().GetFields()[2].Name);
            var user = person.User;

            Assert.Equal(2, user.GetType().GetFields().Length);
            Assert.Equal("Field1", user.GetType().GetFields()[0].Name);
            Assert.Equal("NestedRelation", user.GetType().GetFields()[1].Name);
            var nested = person.User.NestedRelation;

            Assert.Equal(2, nested.GetType().GetFields().Length);
            Assert.Equal("Id", nested.GetType().GetFields()[0].Name);
            Assert.Equal("Name", nested.GetType().GetFields()[1].Name);
        }