public async Task Should_chain_in_order2() { /* Given */ var values = new List <int>(); var builder = new ResolverBuilder(); builder.Use((context, next) => { values.Add(0); return(next(context)); }); builder.Use((context, next) => { var result = next(context); values.Add(1); return(result); }); builder.Use((context, next) => { values.Add(2); return(next(context)); }); builder.Run(context => new ValueTask <IResolverResult>(Resolve.As(42))); /* When */ var resolver = builder.Build(); await resolver(null); /* Then */ Assert.Equal(new[] { 0, 2, 1 }, values.ToArray()); }
public static ISchema InitializeSchema() { var events = new SingleValueEventChannel(); var builder = new SchemaBuilder(); Sdl.Import(Parser.ParseDocument( @" type Query { simple: String } type Mutation { simple: String } type Subscription { simple: String } schema { query: Query mutation: Mutation subscription: Subscription } "), builder); var resolvers = new ResolverMap { { "Query", new FieldResolverMap { { "simple", context => new ValueTask <IResolveResult>(Resolve.As("value")) } } }, { "Mutation", new FieldResolverMap { { "simple", context => new ValueTask <IResolveResult>(Resolve.As("value")) } } }, { "Subscription", new FieldResolverMap() { { "simple", (context, unsubscribe) => ResolveSync.Subscribe(events, unsubscribe), context => new ValueTask <IResolveResult>(Resolve.As(context.ObjectValue)) } } } }; var schema = SchemaTools.MakeExecutableSchema( builder, resolvers, resolvers); return(schema); }
public async ValueTask <IResolverResult> AddMessageAsync(IResolverContext context) { var input = context.GetObjectArgument <InputMessage>("message"); var message = await context.Use <IChat>().AddMessageAsync( "1", input.Content); return(Resolve.As(message)); }
public async ValueTask <IResolveResult> AddMessageAsync(ResolverContext context) { var input = context.GetArgument <InputMessage>("message"); var message = await _chat.AddMessageAsync( "1", input.Content); return(Resolve.As(message)); }
public ExecutionPathFacts() { // schema var builder = new SchemaBuilder(); builder.Add((TypeSystemDocument) @" type Node { child: Node path: [String] value: String children: [Node] } type Query { root: Node } type Mutation { root: Node } "); var resolvers = new ResolversMap { { "Query", new FieldResolversMap { { "root", context => new ValueTask <IResolverResult>(Resolve.As(new { })) } } }, { "Mutation", new FieldResolversMap { { "root", context => new ValueTask <IResolverResult>(Resolve.As(new { })) } } }, { "Node", new FieldResolversMap { { "child", context => new ValueTask <IResolverResult>(Resolve.As(new { })) }, { "children", context => new ValueTask <IResolverResult>(Resolve.As(new[] { new { id = 0 }, new { id = 1 } })) }, { "value", context => new ValueTask <IResolverResult>(Resolve.As("value")) }, { "path", context => new ValueTask <IResolverResult>(Resolve.As(context.Path.Segments)) } } } }; _schema = builder.Build(resolvers).Result; }
public ExecutionPathFacts() { // schema var builder = new SchemaBuilder(); builder.Object("Node", out var node) .Connections(connect => connect .Field(node, "child", node) .Field(node, "path", new List(ScalarType.String)) .Field(node, "value", ScalarType.String) .Field(node, "children", new List(node))); builder.Query(out var query) .Connections(connect => connect .Field(query, "root", node)); builder.Mutation(out var mutation) .Connections(connect => connect .Field(mutation, "root", node)); var schema = builder.Build(); var resolvers = new ResolverMap { { "Query", new FieldResolverMap { { "root", context => new ValueTask <IResolveResult>(Resolve.As(new { })) } } }, { "Mutation", new FieldResolverMap { { "root", context => new ValueTask <IResolveResult>(Resolve.As(new { })) } } }, { "Node", new FieldResolverMap { { "child", context => new ValueTask <IResolveResult>(Resolve.As(new { })) }, { "children", context => new ValueTask <IResolveResult>(Resolve.As(new[] { new { id = 0 }, new { id = 1 } })) }, { "value", context => new ValueTask <IResolveResult>(Resolve.As("value")) }, { "path", context => new ValueTask <IResolveResult>(Resolve.As(context.Path.Segments)) } } } }; _schema = SchemaTools.MakeExecutableSchema(schema, resolvers); }
public async Task Make_executable_schema() { /* Given */ var builder = new SchemaBuilder() .Sdl(@" type Query { field1: Int! } schema { query: Query } " ); var resolvers = new ObjectTypeMap { { "Query", new FieldResolversMap { { "field1", async context => { await Task.Delay(1); return(Resolve.As(1)); } } } } }; /* When */ var executableSchema = SchemaTools.MakeExecutableSchema( builder: builder, resolvers: resolvers, subscribers: null, converters: null, directives: null); /* Then */ var result = await Executor.ExecuteAsync( new ExecutionOptions { Document = Parser.ParseDocument(@"{ field1 }"), Schema = executableSchema }); result.ShouldMatchJson( @"{ ""data"": { ""field1"": 1 } }"); }
public async ValueTask <IResolveResult> EditMessageAsync(ResolverContext context) { var id = context.GetArgument <string>("id"); var input = context.GetArgument <InputMessage>("message"); var message = await _chat.EditMessageAsync( id, input.Content); return(Resolve.As(message)); }
public static Task <ISchema> InitializeSchema() { var events = new SingleValueEventChannel(); var builder = new SchemaBuilder() .Add( @" type Query { simple: String } type Mutation { simple: String } type Subscription { simple: String } schema { query: Query mutation: Mutation subscription: Subscription } "); var resolvers = new ResolversMap { { "Query", new FieldResolversMap { { "simple", context => new ValueTask <IResolverResult>(Resolve.As("value")) } } }, { "Mutation", new FieldResolversMap { { "simple", context => new ValueTask <IResolverResult>(Resolve.As("value")) } } }, { "Subscription", new FieldResolversMap { { "simple", (context, unsubscribe) => ResolveSync.Subscribe(events, unsubscribe), context => new ValueTask <IResolverResult>(Resolve.As(context.ObjectValue)) } } } }; return(builder.Build(resolvers, resolvers)); }
public void Setup() { _schema = Utils.InitializeSchema(); _query = Utils.InitializeQuery(); _mutation = Utils.InitializeMutation(); _subscription = Utils.InitializeSubscription(); _defaultRulesMap = ExecutionRules.All; _resolverChain = new ResolverBuilder() .Use((context, next) => next(context)) .Use((context, next) => next(context)) .Run(context => new ValueTask <IResolveResult>(Resolve.As(42))) .Build(); _resolver = context => new ValueTask <IResolveResult>(Resolve.As(42)); }
public async Task Make_executable_schema() { /* Given */ var schema1 = new SchemaBuilder() .Query(out var query1) .Connections(connect => connect.Field(query1, "field1", ScalarType.Int) ) .Build(); var resolvers = new ResolverMap { { query1.Name, new FieldResolverMap { { "field1", async context => { await Task.Delay(1); return(Resolve.As(1)); } } } } }; /* When */ var executableSchema = SchemaTools.MakeExecutableSchema( schema: schema1, resolvers: resolvers, subscribers: null); /* Then */ var result = await Executor.ExecuteAsync( new ExecutionOptions { Document = Parser.ParseDocument(@"{ field1 }"), Schema = executableSchema }); result.ShouldMatchJson( @"{ ""data"": { ""field1"": 1 } }"); }
public async Task Part2_BindResolvers_Manual() { // Create builder and load sdl var builder = new SchemaBuilder() .Sdl(@" type Query { name: String } "); // Get query type builder.GetQuery(out var query); // Connections are used to defined fields and resolvers. // Connections method can be called multiple times. builder.Connections(connections => { // Get or add resolver builder for Query.name field var nameResolverBuilder = connections .GetOrAddResolver(query, "name"); // "Run" allows us to define an end of the resolver // chain. You can add "middlewares" using "Use". nameResolverBuilder .Run(context => { // Create result using Test as the value var result = Resolve.As("Test"); // Resolvers can be sync or async so // ValueTask result is used to reduce // allocations return(new ValueTask <IResolverResult>(result)); }); }); // Build schema with the resolver var schema = builder.Build(); // Get resolver for Query.name field var nameResolver = schema.GetResolver(schema.Query.Name, "name"); // Execute the resolver. This is normally handled by the executor. var nameValue = await nameResolver(null); Assert.Equal("Test", nameValue.Value); }
public NullErrorsFacts() { var builder = new SchemaBuilder(); builder.Object("Nest", out var nested) .Connections(connect => connect .Field(nested, "nestedNonNull", ScalarType.NonNullString)); builder.Query(out var query) .Connections(connect => connect .Field(query, "nonNull", ScalarType.NonNullString) .Field(query, "nonNullNested", new NonNull(nested)) .Field(query, "nonNullListItem", new List(ScalarType.NonNullString)) .Field(query, "nonNullList", new NonNull(new List(ScalarType.String))) .Field(query, "nullableNested", nested) .Field(query, "nullable", ScalarType.String)); var nestedNonNullData = new Dictionary <string, string> { ["nestedNonNull"] = null }; IResolverMap resolvers = new ResolverMap { ["Query"] = new FieldResolverMap { { "nonNull", context => new ValueTask <IResolveResult>(Resolve.As(null)) }, { "nonNullNested", context => new ValueTask <IResolveResult>(Resolve.As(nestedNonNullData)) }, { "nonNullListItem", context => new ValueTask <IResolveResult>(Resolve.As(new[] { "str", null, "str" })) }, { "nonNullList", context => new ValueTask <IResolveResult>(Resolve.As(null)) }, { "nullableNested", context => new ValueTask <IResolveResult>(Resolve.As(nestedNonNullData)) }, { "nullable", context => new ValueTask <IResolveResult>(Resolve.As("hello")) } }, ["Nest"] = new FieldResolverMap { { "nestedNonNull", Resolve.PropertyOf <Dictionary <string, string> >(d => d["nestedNonNull"]) } } }; _schema = SchemaTools.MakeExecutableSchema( builder, resolvers); }
public async Task Should_propagate_resolved_value() { /* Given */ var builder = new ResolverBuilder(); builder .Use((context, next) => next(context)) .Use((context, next) => next(context)) .Use((context, next) => next(context)); builder.Run(context => new ValueTask <IResolverResult>(Resolve.As(42))); /* When */ var resolver = builder.Build(); var result = await resolver(null); /* Then */ Assert.Equal(42, result.Value); }
public async Task Part2_BindResolvers_SchemaBuilder_Maps() { // Create builder and load sdl var builder = new SchemaBuilder() .Sdl(@" type Query { name: String } "); // Get query type builder.GetQuery(out var query); // Bind resolvers from ObjectTypeMap builder.UseResolversAndSubscribers( new ObjectTypeMap { { query.Name, new FieldResolversMap { { "name", context => { var result = Resolve.As("Test"); return(new ValueTask <IResolverResult>(result)); } } } } }); // Build schema var schema = builder.Build(); // Get resolver for Query.name field var nameResolver = schema.GetResolver(schema.Query.Name, "name"); // Execute the resolver. This is normally handled by the executor. var nameValue = await nameResolver(null); Assert.Equal("Test", nameValue.Value); }
public void Should_not_call_chain_until_resolver_executed() { /* Given */ var values = new List <int>(); var builder = new ResolverBuilder(); builder.Use((context, next) => { values.Add(0); return(next(context)); }); builder.Run(context => new ValueTask <IResolverResult>(Resolve.As(42))); /* When */ builder.Build(); /* Then */ Assert.Equal(new int[] {}, values.ToArray()); }
public static CreateDirectiveVisitor AuthorizeVisitor(Func <int, ClaimsPrincipal> fetchUser) { return(builder => new DirectiveVisitor { FieldDefinition = (directive, fieldDefinition) => { return fieldDefinition.WithResolver(resolver => resolver.Use((context, next) => { var requiredRole = directive.GetArgument <string>("role"); var user = fetchUser(42); if (!user.HasClaim("role", requiredRole)) { return new ValueTask <IResolveResult>(Resolve.As("requires admin role. " + "todo(pekka): should throw error or return error or??")); } return next(context); }).Run(fieldDefinition.Resolver)); } }); }
public async Task Part2_BindResolvers_Manual() { // Create builder and load sdl var builder = new SchemaBuilder() .Add(@" type Query { name: String } "); // Build schema with the resolver var schema = await builder.Build(new SchemaBuildOptions { Resolvers = new ResolversMap { { "Query", "name", context => { // Create result using Test as the value var result = Resolve.As("Test"); // Resolvers can be sync or async so // ValueTask result is used to reduce // allocations return new ValueTask<IResolverResult>(result); } } } }); // Get resolver for Query.name field var nameResolver = schema.GetResolver(schema.Query.Name, "name")!; // Execute the resolver. This is normally handled by the executor. var nameValue = await nameResolver(null); Assert.Equal("Test", nameValue.Value); }
public ExecutorFacts() { Model = new EventsModel(); Resolvers = new ResolverMap { { "Success", new FieldResolverMap { { "id", Resolve.PropertyOf <EventsModel.Success>(m => m.Id) }, { "event", Resolve.PropertyOf <EventsModel.Success>(m => m.Event) } } }, { "Failure", new FieldResolverMap { { "message", Resolve.PropertyOf <EventsModel.Failure>(m => m.Message) } } }, { "Event", new FieldResolverMap { { "id", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Id) }, { "type", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Type) }, { "payload", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Payload) } } }, { "NewEvent", new FieldResolverMap { { "type", Resolve.PropertyOf <EventsModel.NewEvent>(type => type.Type) }, { "payload", Resolve.PropertyOf <EventsModel.NewEvent>(type => type.Payload) } } }, { "Query", new FieldResolverMap { { "events", context => new ValueTask <IResolveResult>(Resolve.As(Model.Events)) } } }, { "Mutation", new FieldResolverMap { { "create", async context => { var newEvent = context.GetArgument <EventsModel.NewEvent>("event"); if (newEvent.Payload == null) { return(Resolve.As( context.Schema.GetNamedType <ObjectType>("Failure"), new EventsModel.Failure("Payload should be given"))); } var id = await Model.AddAsync(newEvent); var ev = Model.Events.Single(e => e.Id == id); return(Resolve.As( context.Schema.GetNamedType <ObjectType>("Success"), new EventsModel.Success(id, ev))); } } } }, { "Subscription", new FieldResolverMap { { "events", async(context, unsubscribe) => { await Task.Delay(0); var source = Model.Subscribe(unsubscribe); return(source); }, context => new ValueTask <IResolveResult>(Resolve.As(context.ObjectValue)) } } } }; var schema = graphql.sdl.Sdl.Schema(Parser.ParseDocument(Sdl)); Schema = SchemaTools.MakeExecutableSchema( schema, Resolvers, Resolvers); }
public async ValueTask <IResolveResult> GetMessagesAsync(ResolverContext context) { var messages = await _chat.GetMessagesAsync(100); return(Resolve.As(messages)); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var eventManager = new EventManager(); var sdl = @" input InputEvent { type: String! message: String! } type Event { type: String! message: String! } type Query { hello: String! } type Mutation { add(event: InputEvent!): Event } type Subscription { events: Event! } schema { query: Query mutation: Mutation } "; var builder = new SchemaBuilder() .Sdl(Parser.ParseDocument(sdl)); var resolvers = new ResolverMap { { "Event", new FieldResolverMap() { { "type", Resolve.PropertyOf <Event>(ev => ev.Type) }, { "message", Resolve.PropertyOf <Event>(ev => ev.Message) } } }, { "Query", new FieldResolverMap { { "hello", context => new ValueTask <IResolveResult>(Resolve.As("world")) } } }, { "Mutation", new FieldResolverMap() { { "add", async context => { var input = context.GetArgument <InputEvent>("event"); var ev = await eventManager.Add(input.Type, input.Message); return(Resolve.As(ev)); } } } }, { "Subscription", new FieldResolverMap { { "events", (context, ct) => { var events = eventManager.Subscribe(ct); return(new ValueTask <ISubscribeResult>(events)); }, context => new ValueTask <IResolveResult>(Resolve.As(context.ObjectValue)) } } } }; var executable = SchemaTools.MakeExecutableSchemaWithIntrospection( builder, resolvers, resolvers); services.AddSingleton(provider => executable); services.AddSingleton(provider => eventManager); // web socket server services.AddTankaSchemaOptions() .Configure <ISchema>((options, schema) => options.GetSchema = query => new ValueTask <ISchema>(schema)); services.AddTankaWebSocketServer(); services.AddSignalR(options => { options.EnableDetailedErrors = true; }) .AddTankaServerHub(); }
public static ValueTask <IResolveResult> Sync(IEnumerable result) { return(new ValueTask <IResolveResult>(Resolve.As(result))); }
public static ValueTask <IResolveResult> Sync(object result) { return(new ValueTask <IResolveResult>(Resolve.As(result))); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var eventManager = new EventManager(); var sdl = @" input InputEvent { type: String! message: String! } type Event { type: String! message: String! } type Query { hello: String! } type Mutation { add(event: InputEvent!): Event } type Subscription { events: Event! } schema { query: Query mutation: Mutation } "; var builder = new SchemaBuilder() .Sdl(Parser.ParseTypeSystemDocument(sdl)); var resolvers = new ObjectTypeMap { { "Event", new FieldResolversMap { { "type", Resolve.PropertyOf <Event>(ev => ev.Type) }, { "message", Resolve.PropertyOf <Event>(ev => ev.Message) } } }, { "Query", new FieldResolversMap { { "hello", context => new ValueTask <IResolverResult>(Resolve.As("world")) } } }, { "Mutation", new FieldResolversMap { { "add", async context => { var input = context.GetObjectArgument <InputEvent>("event"); var ev = await eventManager.Add(input.Type, input.Message); return(Resolve.As(ev)); } } } }, { "Subscription", new FieldResolversMap { { "events", (context, ct) => { var events = eventManager.Subscribe(ct); return(new ValueTask <ISubscriberResult>(events)); }, context => new ValueTask <IResolverResult>(Resolve.As(context.ObjectValue)) } } } }; var executable = SchemaTools.MakeExecutableSchemaWithIntrospection( builder, resolvers, resolvers); services.AddSingleton(provider => eventManager); // configure common options and add web socket services services.AddTankaGraphQL() .ConfigureSchema(() => new ValueTask <ISchema>(executable)) .ConfigureWebSockets(); // add SignalR services and Tanka SignalR hub services services.AddSignalR() .AddTankaGraphQL(); }
public async Task Authorize_field_directive_sdl() { /* Given */ var builder = new SchemaBuilder() .Sdl(Parser.ParseDocument(@" directive @authorize( role: String =""user"" ) on FIELD_DEFINITION type Query { requiresAdmin: String @authorize(role:""admin"") requiresUser: String @authorize } schema { query: Query } ")); var resolvers = new ResolverMap { { "Query", new FieldResolverMap { { "requiresAdmin", context => new ValueTask <IResolveResult>(Resolve.As("Hello Admin!")) }, { "requiresUser", context => new ValueTask <IResolveResult>(Resolve.As("Hello User!")) } } } }; // mock user and user store var user = new ClaimsPrincipal(new ClaimsIdentity(new [] { new Claim("role", "user"), })); ClaimsPrincipal FetchUser(int id) => user; /* When */ var schema = SchemaTools.MakeExecutableSchema( builder, resolvers, directives: new Dictionary <string, CreateDirectiveVisitor> { // register directive visitor to be used when authorizeType.Name present ["authorize"] = AuthorizeVisitor(FetchUser) }); var result = await Executor.ExecuteAsync(new ExecutionOptions { Document = Parser.ParseDocument(@"{ requiresAdmin requiresUser }"), Schema = schema }); /* Then */ result.ShouldMatchJson(@" { ""data"": { ""requiresAdmin"": null, ""requiresUser"": ""Hello User!"" }, ""errors"": [ { ""message"": ""requires admin role. "", ""locations"": [ { ""end"": 28, ""start"": 2 } ], ""path"": [ ""requiresAdmin"" ], ""extensions"": { ""code"": ""EXCEPTION"" } } ] } "); }
public async Task Authorize_field_directive() { /* Given */ var authorizeType = new DirectiveType( "authorize", new[] { DirectiveLocation.FIELD_DEFINITION }, new Args { { "role", ScalarType.NonNullString, "user", "Required role" } }); var builder = new SchemaBuilder(); builder.Include(authorizeType); builder.Query(out var query) .Connections(connect => connect .Field(query, "requiresAdmin", ScalarType.String, directives: new[] { authorizeType.CreateInstance(new Dictionary <string, object> { // this will override the default value of the DirectiveType ["role"] = "admin" }) }) .Field(query, "requiresUser", ScalarType.String, directives: new[] { // this will use defaultValue from DirectiveType authorizeType.CreateInstance() })); var resolvers = new ResolverMap { { query.Name, new FieldResolverMap { { "requiresAdmin", context => new ValueTask <IResolveResult>(Resolve.As("Hello Admin!")) }, { "requiresUser", context => new ValueTask <IResolveResult>(Resolve.As("Hello User!")) } } } }; // mock user and user store var user = new ClaimsPrincipal(new ClaimsIdentity(new [] { new Claim("role", "user"), })); ClaimsPrincipal FetchUser(int id) => user; /* When */ var schema = SchemaTools.MakeExecutableSchema( builder, resolvers, directives: new Dictionary <string, CreateDirectiveVisitor> { // register directive visitor to be used when authorizeType.Name present [authorizeType.Name] = AuthorizeVisitor(FetchUser) }); var result = await Executor.ExecuteAsync(new ExecutionOptions { Document = Parser.ParseDocument(@"{ requiresAdmin requiresUser }"), Schema = schema }); /* Then */ result.ShouldMatchJson( @" { ""data"": { ""requiresAdmin"": null, ""requiresUser"": ""Hello User!"" }, ""errors"": [ { ""message"": ""requires admin role. "", ""locations"": [ { ""end"": 28, ""start"": 2 } ], ""path"": [ ""requiresAdmin"" ], ""extensions"": { ""code"": ""EXCEPTION"" } } ] } "); }
public ExecutorFacts(ITestOutputHelper atr) { Model = new EventsModel(); Resolvers = new ResolversMap { { "Success", new FieldResolversMap { { "id", Resolve.PropertyOf <EventsModel.Success>(m => m.Id) }, { "event", Resolve.PropertyOf <EventsModel.Success>(m => m.Event) } } }, { "Failure", new FieldResolversMap { { "message", Resolve.PropertyOf <EventsModel.Failure>(m => m.Message) } } }, { "Event", new FieldResolversMap { { "id", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Id) }, { "type", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Type) }, { "payload", Resolve.PropertyOf <EventsModel.Event>(ev => ev.Payload) } } }, { "NewEvent", new FieldResolversMap { { "type", Resolve.PropertyOf <EventsModel.NewEvent>(type => type.Type) }, { "payload", Resolve.PropertyOf <EventsModel.NewEvent>(type => type.Payload) } } }, { "Query", new FieldResolversMap { { "events", context => new ValueTask <IResolverResult>(Resolve.As(Model.Events)) } } }, { "Mutation", new FieldResolversMap { { "create", async context => { var newEvent = context.GetObjectArgument <EventsModel.NewEvent>("event"); if (newEvent.Payload == null) { return(Resolve.As( context.ExecutionContext.Schema.GetRequiredNamedType <ObjectDefinition>("Failure"), new EventsModel.Failure("Payload should be given"))); } var id = await Model.AddAsync(newEvent); var ev = Model.Events.Single(e => e.Id == id); return(Resolve.As( context.ExecutionContext.Schema.GetRequiredNamedType <ObjectDefinition>("Success"), new EventsModel.Success(id, ev))); } } } }, { "Subscription", new FieldResolversMap { { "events", async(context, unsubscribe) => { await Task.Delay(0); var source = Model.Subscribe(unsubscribe); return(source); }, context => new ValueTask <IResolverResult>(Resolve.As(context.ObjectValue)) } } } }; Schema = new SchemaBuilder() .Add((TypeSystemDocument)Sdl) .Build(Resolvers, Resolvers).Result; }
public async Task Create_Field_Resolver() { /* Given */ var builder = new SchemaBuilder(); builder.Query(out var query) .Connections(connections => { connections.Field(query, "field1", ScalarType.String, "test field", resolve => resolve.Run(context => new ValueTask <IResolveResult>(Resolve.As(42)))); }); /* When */ var sut = builder.Build(); /* Then */ var result = await sut.GetResolver(query.Name, "field1")(null); Assert.Equal(42, result.Value); }
public async Task Part3_ApplyDirectives_on_Object_fields() { // Create builder, load sdl with our types // and bind the resolvers var builder = new SchemaBuilder() .Add(@" directive @duplicate on FIELD_DEFINITION type Query { name: String @duplicate } "); // todo: This is not currently working and resolvers are being modified but // those modified resolvers are not taken into use by anything // build schema with resolvers and directives var schema = await builder.Build(new SchemaBuildOptions { Resolvers = new ResolversMap { { "Query", new FieldResolversMap { { "name", context => { var result = Resolve.As("Test"); return new ValueTask<IResolverResult>(result); } } } } }, DirectiveVisitorFactories = new Dictionary<string, CreateDirectiveVisitor> { // Apply directives to schema by providing a visitor which // will transform the fields with the directive into new // fields with the directive logic. Note that the original // field will be replaced. ["duplicate"] = _ => new DirectiveVisitor { // Visitor will visit field definitions FieldDefinition = (directive, fieldDefinition) => { // We will create new field definition with // new resolver. New resolver will execute the // original resolver, duplicate value and return it return fieldDefinition .WithResolver(resolver => resolver.Use(async (context, next) => { // We need to first call the original resolver to // get the initial value var result = await next(context); // for simplicity we expect value to be string var initialValue = result.Value.ToString(); // return new value return Resolve.As(initialValue + initialValue); }).Run(fieldDefinition.Resolver)); } } } }); // Get resolver for Query.name field var nameResolver = schema.GetResolver(schema.Query.Name, "name")!; // Execute the resolver. This is normally handled by the executor. var nameValue = await nameResolver(null); Assert.Equal("TestTest", nameValue.Value); }
public async ValueTask <IResolverResult> GetMessagesAsync(IResolverContext context) { var messages = await context.Use <IChat>().GetMessagesAsync(100); return(Resolve.As(messages)); }