private async Task <ISchema> Create() { // Do some async work to build the schema. For example // load SDL from file await Task.Delay(0); // Build simple schema from SDL string var builder = new SchemaBuilder() .Sdl( @" type Query { firstName: String! lastName: String! } schema { query: Query } "); // Bind resolvers and build return(SchemaTools .MakeExecutableSchemaWithIntrospection( builder, new ObjectTypeMap() { ["Query"] = new FieldResolversMap() { { "firstName", context => ResolveSync.As("Tanka") }, { "lastName", UseService() } } })); }
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); }
/// <summary> /// Return introspection schema for given schema /// </summary> /// <param name="schema"></param> /// <returns></returns> public static ISchema Schema(ISchema schema) { var introspectionSchema = IntrospectionSchema.Create(); var introspectionResolvers = new IntrospectionResolvers(schema); return(SchemaTools.MakeExecutableSchema( introspectionSchema, introspectionResolvers)); }
public CoolStoreSchema(ICoolStoreResolverService resolverService) { var schema = FromIdlAsync().Result; var resolvers = new CoolStoreResolvers(resolverService); CoolStore = SchemaTools.MakeExecutableSchemaWithIntrospection( schema, resolvers, resolvers).Result; }
public ChatSchemas(IChatResolverService resolverService) { var builder = IdlSchema.Load(); var resolvers = new ChatResolvers(resolverService); Chat = SchemaTools.MakeExecutableSchemaWithIntrospection( builder, resolvers, resolvers); }
public ISchema CreateSchema(Starwars starwars) { var schema = StarwarsSchema.Create(); var resolvers = StarwarsResolvers.BuildResolvers(starwars); var executable = SchemaTools.MakeExecutableSchemaWithIntrospection( schema, resolvers); return(executable); }
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 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 ChatSchemas(IChatResolverService resolverService) { var builder = IdlSchema.Load(); var resolvers = new ChatResolvers(resolverService); // add cost directive support to schema builder.Include(CostAnalyzer.CostDirective); // build executable schema Chat = SchemaTools.MakeExecutableSchemaWithIntrospection( builder, resolvers, resolvers); }
public CoolStoreSchema(IHttpContextAccessor httpContext, ICoolStoreResolverService resolverService) { _httpContext = httpContext; var schema = IdlSchema.CreateAsync().Result; var schemaBuilder = new SchemaBuilder(schema); var resolvers = new CoolStoreResolvers(resolverService); CoolStore = SchemaTools.MakeExecutableSchemaWithIntrospection( schemaBuilder, resolvers, resolvers, new Dictionary <string, CreateDirectiveVisitor> { ["authorize"] = AuthorizeVisitor() }); }
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 async Task Part2_BindResolvers_SchemaTools_Maps() { // Create builder and load sdl var builder = new SchemaBuilder() .Sdl(@" type Query { name: String } "); // Get query type builder.GetQuery(out var query); // Build schema by binding resolvers from ObjectTypeMap var schema = SchemaTools.MakeExecutableSchema( builder, new ObjectTypeMap { { query.Name, new FieldResolversMap { { "name", context => { var result = Resolve.As("Test"); 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); }
private async Task <ISchema> Create(ICacheEntry cacheEntry) { cacheEntry.SetSlidingExpiration(TimeSpan.FromHours(6)); try { var schemaBuilder = await SchemaLoader.Load(); var resolvers = new SchemaResolvers(); var schema = SchemaTools.MakeExecutableSchemaWithIntrospection( schemaBuilder, resolvers, resolvers); return(schema); } catch (Exception e) { Console.WriteLine(e); throw; } }
public async Task Subscriptions() { /* Given */ var schemaOneBuilder = new SchemaBuilder() .Sdl( @" type User { id: ID! name: String! } type Query { userById(id: ID!): User } type Subscription { userAdded: User } schema { query: Query subscription: Subscription } "); var schemaTwoBuilder = new SchemaBuilder() .Sdl( @" type Address { city: String! } type User { address: Address! } type Query { } type Subscription { } " ); var schemaOne = RemoteSchemaTools.MakeRemoteExecutable( schemaOneBuilder, RemoteLinks.Static(new ExecutionResult { Data = new Dictionary <string, object> { ["userAdded"] = new Dictionary <string, object> { ["id"] = "1", ["name"] = "name" } } })); var schemaTwo = SchemaTools.MakeExecutableSchema( schemaTwoBuilder, new ObjectTypeMap { ["Address"] = new FieldResolversMap { { "city", context => ResolveSync.As(context.ObjectValue) } }, ["User"] = new FieldResolversMap { { "address", context => ResolveSync.As("Vantaa") } } }); var schema = new SchemaBuilder() .Merge(schemaOne, schemaTwo) .Build(); var unsubscribe = new CancellationTokenSource(TimeSpan.FromSeconds(30)); /* When */ var subscriptionResult = await Executor.SubscribeAsync(new ExecutionOptions { Schema = schema, Document = Parser.ParseDocument(@" subscription { userAdded { id name address { city } } }") }, unsubscribe.Token); var result = await subscriptionResult.Source.Reader.ReadAsync(unsubscribe.Token); /* Then */ result.ShouldMatchJson( @" { ""data"": { ""userAdded"": { ""address"": { ""city"": ""Vantaa"" }, ""name"": ""name"", ""id"": ""1"" } } } "); }
// 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 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); }
public async Task Execute_with_StaticLink() { /* Given */ var schemaOneBuilder = new SchemaBuilder() .Sdl( @" type User { id: ID! name: String! } type Query { userById(id: ID!): User } schema { query: Query } "); var schemaTwoBuilder = new SchemaBuilder() .Sdl( @" type Address { city: String! } type User { address: Address! } type Query { } " ); var schemaOne = RemoteSchemaTools.MakeRemoteExecutable( schemaOneBuilder, RemoteLinks.Static(new ExecutionResult { Data = new Dictionary <string, object> { ["userById"] = new Dictionary <string, object> { ["id"] = "1", ["name"] = "name" } } })); var schemaTwo = SchemaTools.MakeExecutableSchema( schemaTwoBuilder, new ObjectTypeMap { ["Address"] = new FieldResolversMap { { "city", context => ResolveSync.As(context.ObjectValue) } }, ["User"] = new FieldResolversMap { { "address", context => ResolveSync.As("Vantaa") } } }); var schema = new SchemaBuilder() .Merge(schemaOne, schemaTwo) .Build(); /* When */ var result = await Executor.ExecuteAsync(new ExecutionOptions { Schema = schema, Document = Parser.ParseDocument(@" { userById(id: ""1"") { id name address { city } } }") }); /* Then */ result.ShouldMatchJson( @" { ""data"": { ""userById"": { ""address"": { ""city"": ""Vantaa"" }, ""name"": ""name"", ""id"": ""1"" } } } "); }
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 async Task Part6_Custom_Scalar() { // Create builder and load sdl var builder = new SchemaBuilder() .Sdl(@" # Custom scalar defined in the SDL scalar Uri type Query { url: Uri! } "); // Get query type builder.GetQuery(out var query); // Build schema by binding resolvers from ObjectTypeMap var schema = SchemaTools.MakeExecutableSchema( builder, new ObjectTypeMap { { query.Name, new FieldResolversMap { { "url", context => ResolveSync.As(new Uri("https://localhost/")) } } } }, converters: new Dictionary <string, IValueConverter>() { // this will add value converter for Uri scalar type ["Uri"] = new InlineConverter( serialize: value => { var uri = (Uri)value; return(uri.ToString()); }, parseValue: value => new Uri(value.ToString()), parseLiteral: value => { if (value.Kind == NodeKind.StringValue) { return(new Uri((StringValue)value)); } throw new ArgumentOutOfRangeException( nameof(value), $"Cannot coerce Uri from value kind: '{value.Kind}'"); }) }); // execute query var result = await Executor.ExecuteAsync(new ExecutionOptions() { Schema = schema, Document = Parser.ParseDocument(@"{ url }") }); var url = result.Data["url"]; Assert.Equal("https://localhost/", url.ToString()); }
// 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 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); }