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); }
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); }
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); }
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); }
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); }
/// <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); }
/// <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); }
/// <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); }
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); }