コード例 #1
0
        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());
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
    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;
    }
コード例 #6
0
        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);
        }
コード例 #7
0
        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
                  }
                }");
        }
コード例 #8
0
        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));
        }
コード例 #9
0
ファイル: Utils.cs プロジェクト: pekkah/tanka-graphql
    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));
    }
コード例 #10
0
ファイル: Benchmarks.cs プロジェクト: qonn/tanka-graphql
        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));
        }
コード例 #11
0
        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
                  }
                }");
        }
コード例 #12
0
        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);
        }
コード例 #13
0
ファイル: NullErrorsFacts.cs プロジェクト: qonn/tanka-graphql
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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());
        }
コード例 #17
0
        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));
                }
            });
        }
コード例 #18
0
    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);
    }
コード例 #19
0
        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);
        }
コード例 #20
0
        public async ValueTask <IResolveResult> GetMessagesAsync(ResolverContext context)
        {
            var messages = await _chat.GetMessagesAsync(100);

            return(Resolve.As(messages));
        }
コード例 #21
0
ファイル: Startup.cs プロジェクト: qonn/tanka-graphql
        // 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();
        }
コード例 #22
0
 public static ValueTask <IResolveResult> Sync(IEnumerable result)
 {
     return(new ValueTask <IResolveResult>(Resolve.As(result)));
 }
コード例 #23
0
 public static ValueTask <IResolveResult> Sync(object result)
 {
     return(new ValueTask <IResolveResult>(Resolve.As(result)));
 }
コード例 #24
0
ファイル: Startup.cs プロジェクト: digvand/tanka-graphql
        // 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();
        }
コード例 #25
0
        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""
                      }
                    }
                  ]
                }
                ");
        }
コード例 #26
0
        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""
                      }
                    }
                  ]
                }
                ");
        }
コード例 #27
0
    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;
    }
コード例 #28
0
        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);
        }
コード例 #29
0
    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);
    }
コード例 #30
0
        public async ValueTask <IResolverResult> GetMessagesAsync(IResolverContext context)
        {
            var messages = await context.Use <IChat>().GetMessagesAsync(100);

            return(Resolve.As(messages));
        }