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 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 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 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 static ResolverMap BuildResolvers(Starwars starwars) { async ValueTask <IResolveResult> ResolveCharacter(ResolverContext context) { var id = (string)context.Arguments["id"]; var character = await starwars.GetCharacter(id).ConfigureAwait(false); return(As(context.Schema.GetNamedType <ObjectType>("Human"), character)); } async ValueTask <IResolveResult> ResolveHuman(ResolverContext context) { var id = (string)context.Arguments["id"]; var human = await starwars.GetHuman(id).ConfigureAwait(false); return(As(human)); } async ValueTask <IResolveResult> ResolveFriends(ResolverContext context) { var character = (Starwars.Character)context.ObjectValue; var friends = character.GetFriends(); await Task.Delay(0).ConfigureAwait(false); return(As(friends.Select(c => As(context.Schema.GetNamedType <ObjectType>("Human"), c)))); } async ValueTask <IResolveResult> ResolveCharacters(ResolverContext context) { await Task.Delay(0).ConfigureAwait(false); return(As(starwars.Characters.Select(c => As(context.Schema.GetNamedType <ObjectType>("Human"), c)))); } async ValueTask <IResolveResult> AddHuman(ResolverContext context) { var humanInput = (IDictionary <string, object>)context.Arguments["human"]; var human = starwars.AddHuman(humanInput["name"].ToString()); await Task.Delay(0).ConfigureAwait(false); return(As(human)); } var resolverMap = new ResolverMap { // Root query ["Query"] = new FieldResolverMap { { "human", ResolveHuman }, { "character", ResolveCharacter }, { "characters", ResolveCharacters } }, // Root mutation ["Mutation"] = new FieldResolverMap { { "addHuman", AddHuman } }, // ObjectType ["Human"] = new FieldResolverMap { { "id", PropertyOf <Starwars.Human>(c => c.Id) }, { "name", PropertyOf <Starwars.Human>(c => c.Name) }, { "homePlanet", PropertyOf <Starwars.Human>(c => c.HomePlanet) }, { "friends", ResolveFriends }, { "appearsIn", PropertyOf <Starwars.Human>(h => h.AppearsIn) } } }; return(resolverMap); }
public ExecutorFacts(ITestOutputHelper atr) { 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)) } } } }; Schema = SchemaTools.MakeExecutableSchema( new SchemaBuilder().Sdl(Parser.ParseDocument(Sdl)), Resolvers, Resolvers); }
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 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 SubscriptionsFacts() { // schema var builder = new SchemaBuilder(); builder.Object("Message", out var messageType) .Connections(connect => connect .Field(messageType, "content", ScalarType.String)); var messageListType = new List(messageType); builder.Query(out var query) .Connections(connect => connect .Field(query, "messages", messageListType)); builder.Subscription(out var subscription) .Connections(connect => connect .Field(subscription, "messageAdded", messageType)); var schema = builder.Build(); // data var messages = new List <Message>(); _messagesChannel = new EventChannel <Message>(); // resolvers ValueTask <IResolveResult> GetMessagesAsync(ResolverContext context) { return(ResolveSync.As(messages)); } ValueTask <ISubscribeResult> OnMessageAdded(ResolverContext context, CancellationToken unsubscribe) { return(ResolveSync.Subscribe(_messagesChannel, unsubscribe)); } ValueTask <IResolveResult> ResolveMessage(ResolverContext context) { return(ResolveSync.As(context.ObjectValue)); } var resolvers = new ResolverMap { ["Query"] = new FieldResolverMap { { "messages", GetMessagesAsync } }, ["Subscription"] = new FieldResolverMap { { "messageAdded", OnMessageAdded, ResolveMessage } }, ["Message"] = new FieldResolverMap { { "content", Resolve.PropertyOf <Message>(r => r.Content) } } }; // make executable _executable = SchemaTools.MakeExecutableSchema( schema, resolvers, resolvers); }
// 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(); }