예제 #1
0
        private async Task RegisterSubscription(
            GraphQLFieldSelection fieldSelection,
            GraphQLSubscriptionType type,
            GraphQLDocument document,
            FieldScope scope)
        {
            var fieldInfo = type.GetFieldInfo(fieldSelection.Name.Value) as GraphQLSubscriptionTypeFieldInfo;

            Expression <Func <object, bool> > filter = null;

            if (fieldInfo.Filter != null)
            {
                filter = entity => (bool)scope.InvokeWithArgumentsSync(
                    fieldSelection.Arguments.ToList(), fieldInfo.Filter, entity);
            }

            await type.EventBus.Subscribe(EventBusSubscription.Create(
                                              fieldInfo.Channel,
                                              this.clientId,
                                              this.subscriptionId.Value,
                                              this.Operation?.Name?.Value ?? "Anonymous",
                                              this.variables,
                                              filter,
                                              this.ast));
        }
예제 #2
0
        private async Task <ExpandoObject> ProcessSubscription(
            GraphQLSubscriptionType type,
            IFieldCollector fieldCollector,
            FieldScope scope)
        {
            var fields           = fieldCollector.CollectFields(type, this.Operation.SelectionSet);
            var field            = fields.Single(); //only single subscription field allowed
            var result           = new ExpandoObject();
            var resultDictionary = (IDictionary <string, object>)result;

            await this.RegisterSubscription(
                field.Value.Single(),
                type,
                this.ast,
                scope);

            resultDictionary.Add("subscriptionId", this.subscriptionId.Value);
            resultDictionary.Add("clientId", this.clientId);

            var returnObject           = new ExpandoObject();
            var returnObjectDictionary = (IDictionary <string, object>)returnObject;

            returnObjectDictionary.Add("data", result);

            if (scope.Errors.Any())
            {
                returnObjectDictionary.Add("errors", scope.Errors);
            }

            return(returnObject);
        }
예제 #3
0
        public async Task <ExpandoObject> ComposeResultForSubscriptions(
            GraphQLComplexType type, GraphQLOperationDefinition operationDefinition)
        {
            if (string.IsNullOrWhiteSpace(this.clientId))
            {
                throw new GraphQLException(
                          "Can't invoke subscription without clientId specified",
                          new ASTNode[] { operationDefinition });
            }

            if (!this.subscriptionId.HasValue)
            {
                throw new GraphQLException(
                          "Can't invoke subscription without subscriptionId specified",
                          new ASTNode[] { operationDefinition });
            }

            var context = this.CreateExecutionContext(operationDefinition);

            var scope = new FieldScope(context, type, null);

            return(await this.ProcessSubscription(
                       (GraphQLSubscriptionType)type,
                       context.FieldCollector,
                       scope));
        }
예제 #4
0
 private async Task <ExpandoObject> TryGetObject(FieldScope scope, GraphQLObjectType input, GraphQLFieldSelection selection, IEnumerable <object> path)
 {
     try
     {
         return(await scope.GetObject(this.context.FieldCollector.CollectFields(input, selection.SelectionSet)));
     }
     catch (GraphQLResolveException)
     {
         return(null);
     }
 }
예제 #5
0
        private object CompleteObjectType(
            GraphQLObjectType input, GraphQLFieldSelection selection, IList <GraphQLArgument> arguments, object parentObject)
        {
            var scope = new FieldScope(
                this.typeTranslator,
                this.valueResolver,
                this.fieldCollector,
                input,
                parentObject);

            scope.arguments = arguments.ToList();

            return(scope.GetObject(this.fieldCollector.CollectFields(input, selection.SelectionSet)));
        }
예제 #6
0
        private dynamic ComposeResultForType(GraphQLObjectType type, GraphQLSelectionSet selectionSet)
        {
            var variableResolver = new VariableResolver(this.variables, this.graphQLSchema.TypeTranslator, this.operation.VariableDefinitions);
            var valueResolver    = new ValueResolver(variableResolver, this.graphQLSchema.TypeTranslator);
            var fieldCollector   = new FieldCollector(this.fragments, valueResolver);

            var scope = new FieldScope(
                this.graphQLSchema.TypeTranslator,
                valueResolver,
                fieldCollector,
                type,
                null);

            return(scope.GetObject(fieldCollector.CollectFields(type, selectionSet)));
        }
예제 #7
0
        private async Task <object> CompleteObjectType(
            GraphQLObjectType input,
            GraphQLFieldSelection selection,
            IList <GraphQLArgument> arguments,
            object parentObject,
            IEnumerable <object> path)
        {
            var aliasOrName = selection.Alias?.Value ?? selection.Name.Value;

            var scope = new FieldScope(this.context, input, parentObject, path.Append(aliasOrName), this.Errors)
            {
                arguments = arguments.ToList()
            };

            return(await this.TryGetObject(scope, input, selection, path));
        }
예제 #8
0
        private async Task <object> IntrospectSchemaIfRequested(
            FieldScope scope, IDictionary <string, IList <GraphQLFieldSelection> > fields)
        {
            if (fields.ContainsKey("__schema"))
            {
                var field = fields["__schema"].Single();
                fields.Remove("__schema");

                return(await scope.CompleteValue(
                           this.graphQLSchema.IntrospectedSchema,
                           this.graphQLSchema.IntrospectedSchema.GetType(),
                           field,
                           field.Arguments.ToList()));
            }

            return(null);
        }
예제 #9
0
        private async Task AppendIntrospectionInfo(
            FieldScope scope, Dictionary <string, IList <GraphQLFieldSelection> > fields, IDictionary <string, object> resultObject)
        {
            var introspectedSchema = await this.IntrospectSchemaIfRequested(scope, fields);

            var introspectedField = await this.IntrospectTypeIfRequested(scope, fields);

            if (introspectedSchema != null)
            {
                resultObject.Remove("__schema");
                resultObject.Add("__schema", introspectedSchema);
            }

            if (introspectedField != null)
            {
                resultObject.Remove("__type");
                resultObject.Add("__type", introspectedField);
            }
        }
예제 #10
0
        private async Task <object> IntrospectTypeIfRequested(
            FieldScope scope, IDictionary <string, IList <GraphQLFieldSelection> > fields)
        {
            if (fields.ContainsKey("__type"))
            {
                var field = fields["__type"].Single();
                fields.Remove("__type");

                var value = await scope.InvokeWithArguments(
                    field.Arguments.ToList(),
                    this.GetTypeIntrospectionLambda());

                return(await scope.CompleteValue(
                           value,
                           value?.GetType(),
                           field,
                           field.Arguments.ToList()));
            }

            return(null);
        }
예제 #11
0
        public async Task <ExpandoObject> ComposeResultForMutation(
            GraphQLComplexType type, GraphQLOperationDefinition operationDefinition)
        {
            var context = this.CreateExecutionContext(operationDefinition);
            var scope   = new FieldScope(context, type, null);

            var fields       = context.FieldCollector.CollectFields(type, operationDefinition.SelectionSet);
            var resultObject = await scope.GetObjectSynchronously(fields);

            await this.AppendIntrospectionInfo(scope, fields, resultObject);

            var returnObject           = new ExpandoObject();
            var returnObjectDictionary = (IDictionary <string, object>)returnObject;

            returnObjectDictionary.Add("data", resultObject);

            if (scope.Errors.Any())
            {
                returnObjectDictionary.Add("errors", scope.Errors);
            }

            return(returnObject);
        }