コード例 #1
0
        public Task <IReadOnlyList <Schema> > GetSchemasByIdAsync(
            [GraphQLType(typeof(NonNullType <ListType <NonNullType <IdType> > >))] string[] ids,
            [Service] IIdSerializer idSerializer,
            [DataLoader] SchemaByIdDataLoader dataLoader,
            CancellationToken cancellationToken)
        {
            if (ids.Length == 0)
            {
                throw new GraphQLException("No ids where provided.");
            }

            var deserializedIds = new Guid[ids.Length];

            for (int i = 0; i < ids.Length; i++)
            {
                IdValue deserializedId = idSerializer.Deserialize(ids[i]);

                if (!deserializedId.TypeName.Equals(nameof(Schema), StringComparison.Ordinal))
                {
                    throw new GraphQLException("The specified id type is invalid.");
                }

                deserializedIds[i] = (Guid)deserializedId.Value;
            }

            return(dataLoader.LoadAsync(deserializedIds, cancellationToken));
        }
コード例 #2
0
        public async Task <CreateClientPayload> CreateClientAsync(
            CreateClientInput input,
            [Service] IClientRepository repository,
            [Service] IIdSerializer idSerializer,
            [DataLoader] SchemaByIdDataLoader dataLoader,
            CancellationToken cancellationToken)
        {
            IdValue deserializedId = idSerializer.Deserialize(input.SchemaId);

            if (!deserializedId.TypeName.Equals(nameof(Schema), StringComparison.Ordinal))
            {
                throw new GraphQLException("The specified id type is invalid.");
            }

            Schema schema = await dataLoader.LoadAsync(
                (Guid)deserializedId.Value, cancellationToken)
                            .ConfigureAwait(false);

            var client = new Client(schema.Id, input.Name, input.Description);

            await repository.AddClientAsync(
                client, cancellationToken)
            .ConfigureAwait(false);

            return(new CreateClientPayload(schema, client, input.ClientMutationId));
        }
コード例 #3
0
        public override void OnBeforeCompleteType(
            ITypeCompletionContext completionContext,
            DefinitionBase definition,
            IDictionary <string, object> contextData)
        {
            if ((completionContext.IsQueryType ?? false) &&
                definition is ObjectTypeDefinition objectTypeDefinition)
            {
                ObjectFieldDefinition typeNameField = objectTypeDefinition.Fields.First(
                    t => t.Name.Equals(IntrospectionFields.TypeName) && t.IsIntrospectionField);
                var index = objectTypeDefinition.Fields.IndexOf(typeNameField) + 1;

                var descriptor = ObjectFieldDescriptor.New(
                    completionContext.DescriptorContext,
                    _node);

                IIdSerializer serializer =
                    completionContext.Services.GetService <IIdSerializer>() ??
                    new IdSerializer();

                descriptor
                .Argument(_id, a => a.Type <NonNullType <IdType> >())
                .Type <NodeType>()
                .Resolve(async ctx =>
                {
                    var id = ctx.ArgumentValue <string>(_id);
                    IdValue deserializedId = serializer.Deserialize(id);

                    ctx.LocalContextData = ctx.LocalContextData
                                           .SetItem(WellKnownContextData.Id, deserializedId.Value)
                                           .SetItem(WellKnownContextData.Type, deserializedId.TypeName);

                    if (ctx.Schema.TryGetType(deserializedId.TypeName,
                                              out ObjectType type) &&
                        type.ContextData.TryGetValue(
                            RelayConstants.NodeResolverFactory,
                            out object?o) &&
                        o is Func <IServiceProvider, INodeResolver> factory)
                    {
                        INodeResolver resolver = factory.Invoke(ctx.Services);
                        return(await resolver.ResolveAsync(ctx, deserializedId.Value)
                               .ConfigureAwait(false));
                    }

                    return(null);
                });

                objectTypeDefinition.Fields.Insert(index, descriptor.CreateDefinition());
            }
        }
コード例 #4
0
        public Task <SchemaVersion> GetSchemaVersionByIdAsync(
            [GraphQLType(typeof(NonNullType <IdType>))] string id,
            [Service] IIdSerializer idSerializer,
            [DataLoader] SchemaVersionByIdDataLoader dataLoader,
            CancellationToken cancellationToken)
        {
            IdValue deserializedId = idSerializer.Deserialize(id);

            if (!deserializedId.TypeName.Equals(nameof(SchemaVersion), StringComparison.Ordinal))
            {
                throw new GraphQLException("The specified id type is invalid.");
            }

            return(dataLoader.LoadAsync((Guid)deserializedId.Value, cancellationToken));
        }
コード例 #5
0
ファイル: NodeField.cs プロジェクト: yuriypts/hotchocolate
        private static ObjectFieldDefinition CreateDefinition(
            IDescriptorContext context)
        {
            var descriptor = ObjectFieldDescriptor
                             .New(context, _node);

            IIdSerializer _serializer = null;

            descriptor
            .Argument(_id, a => a.Type <NonNullType <IdType> >())
            .Type <NonNullType <NodeType> >()
            .Resolver(async ctx =>
            {
                IServiceProvider services = ctx.Service <IServiceProvider>();

                if (_serializer is null)
                {
                    _serializer =
                        services.GetService(typeof(IIdSerializer)) is IIdSerializer s
                                ? s
                                : new IdSerializer();
                }

                var id = ctx.Argument <string>(_id);
                IdValue deserializedId = _serializer.Deserialize(id);

                ctx.LocalContextData = ctx.LocalContextData
                                       .SetItem(WellKnownContextData.Id, deserializedId.Value)
                                       .SetItem(WellKnownContextData.Type, deserializedId.TypeName);

                if (ctx.Schema.TryGetType(deserializedId.TypeName,
                                          out ObjectType type) &&
                    type.ContextData.TryGetValue(
                        RelayConstants.NodeResolverFactory,
                        out var o) &&
                    o is Func <IServiceProvider, INodeResolver> factory)
                {
                    INodeResolver resolver = factory.Invoke(services);
                    return(await resolver.ResolveAsync(ctx, deserializedId.Value)
                           .ConfigureAwait(false));
                }

                return(null);
            });

            return(descriptor.CreateDefinition());
        }
コード例 #6
0
        public override void OnBeforeCompleteType(
            ITypeCompletionContext completionContext,
            DefinitionBase?definition,
            IDictionary <string, object?> contextData)
        {
            if ((completionContext.IsQueryType ?? false) &&
                definition is ObjectTypeDefinition objectTypeDefinition)
            {
                ObjectFieldDefinition typeNameField = objectTypeDefinition.Fields.First(
                    t => t.Name.Equals(IntrospectionFields.TypeName) && t.IsIntrospectionField);
                var index = objectTypeDefinition.Fields.IndexOf(typeNameField) + 1;

                var descriptor = ObjectFieldDescriptor.New(
                    completionContext.DescriptorContext,
                    Node);

                IIdSerializer serializer =
                    completionContext.Services.GetService <IIdSerializer>() ??
                    new IdSerializer();

                descriptor
                .Argument(Id, a => a.Type <NonNullType <IdType> >().ID())
                .Type <NodeType>()
                .Resolve(async ctx =>
                {
                    StringValueNode id     = ctx.ArgumentLiteral <StringValueNode>(Id);
                    IdValue deserializedId = serializer.Deserialize(id.Value);

                    ctx.SetLocalValue(NodeId, id.Value);
                    ctx.SetLocalValue(InternalId, deserializedId.Value);
                    ctx.SetLocalValue(InternalType, deserializedId.TypeName);
                    ctx.SetLocalValue(WellKnownContextData.IdValue, deserializedId);

                    if (ctx.Schema.TryGetType(deserializedId.TypeName, out ObjectType type) &&
                        type.ContextData.TryGetValue(NodeResolver, out object?o) &&
                        o is FieldResolverDelegate resolver)
                    {
                        return(await resolver.Invoke(ctx).ConfigureAwait(false));
                    }

                    return(null);
                });

                objectTypeDefinition.Fields.Insert(index, descriptor.CreateDefinition());
            }
        }
コード例 #7
0
        private IdValue DeserializeId(string value)
        {
            if (_idRuntimeType == typeof(int) &&
                value is string rawIntString && int.TryParse(rawIntString, out var intValue))
            {
                return(new IdValue(_schemaName, _nodeTypeName, intValue));
            }

            if (_idRuntimeType == typeof(long) &&
                value is string rawLongString && long.TryParse(rawLongString, out var longValue))
            {
                return(new IdValue(_schemaName, _nodeTypeName, longValue));
            }

            if (_idRuntimeType == typeof(Guid) &&
                value is string rawGuidString && Guid.TryParse(rawGuidString, out Guid guidValue))
            {
                return(new IdValue(_schemaName, _nodeTypeName, guidValue));
            }

            if (_idRuntimeType == typeof(string))
            {
                try
                {
                    return(_idSerializer.Deserialize(value));
                }
                catch
                {
                    // Allow to fall through as this is likely a non-serialized id
                    // There is a slight chance it's not, but we let it slide
                    return(new IdValue(_schemaName, _nodeTypeName, value));
                }
            }

            throw new GraphQLException(
                      ErrorBuilder.New()
                      .SetMessage("The ID `{0}` has an invalid format.", value)
                      .Build());
        }
コード例 #8
0
    private static async ValueTask <object?> ResolveSingleNode(
        IResolverContext context,
        IIdSerializer serializer,
        NameString argumentName)
    {
        StringValueNode nodeId         = context.ArgumentLiteral <StringValueNode>(argumentName);
        IdValue         deserializedId = serializer.Deserialize(nodeId.Value);
        NameString      typeName       = deserializedId.TypeName;

        context.SetLocalValue(NodeId, nodeId.Value);
        context.SetLocalValue(InternalId, deserializedId.Value);
        context.SetLocalValue(InternalType, typeName);
        context.SetLocalValue(WellKnownContextData.IdValue, deserializedId);

        if (context.Schema.TryGetType <ObjectType>(typeName, out ObjectType? type) &&
            type.ContextData.TryGetValue(NodeResolver, out var o) &&
            o is FieldResolverDelegate resolver)
        {
            return(await resolver.Invoke(context).ConfigureAwait(false));
        }

        return(null);
    }
コード例 #9
0
        public async Task <UpdateEnvironmentPayload?> UpdateEnvironmentAsync(
            UpdateEnvironmentInput input,
            [Service] IIdSerializer idSerializer,
            [Service] IEnvironmentRepository repository,
            CancellationToken cancellationToken)
        {
            IdValue deserializedId = idSerializer.Deserialize(input.Id);

            if (!deserializedId.TypeName.Equals(nameof(Environment), StringComparison.Ordinal))
            {
                throw new GraphQLException("The specified id type is invalid.");
            }

            var environment = new Environment(
                (Guid)deserializedId.Value,
                input.Name,
                input.Description);

            await repository.UpdateEnvironmentAsync(environment, cancellationToken)
            .ConfigureAwait(false);

            return(new UpdateEnvironmentPayload(environment, input.ClientMutationId));
        }
コード例 #10
0
        public async Task <UpdateSchemaPayload> UpdateSchema(
            UpdateSchemaInput input,
            [Service] IIdSerializer idSerializer,
            [Service] ISchemaRepository repository,
            CancellationToken cancellationToken)
        {
            IdValue deserializedId = idSerializer.Deserialize(input.Id);

            if (!deserializedId.TypeName.Equals(nameof(Schema), StringComparison.Ordinal))
            {
                throw new GraphQLException(Resources.General_IdTypeInvalid);
            }

            var schema = new Schema(
                (Guid)deserializedId.Value,
                input.Name,
                input.Description);

            await repository.UpdateSchemaAsync(schema, cancellationToken)
            .ConfigureAwait(false);

            return(new UpdateSchemaPayload(schema, input.ClientMutationId));
        }
コード例 #11
0
    private static async ValueTask <object?> ResolveManyNode(
        IResolverContext context,
        IIdSerializer serializer)
    {
        if (context.ArgumentKind(Ids) == ValueKind.List)
        {
            ListValueNode    list  = context.ArgumentLiteral <ListValueNode>(Ids);
            Task <object?>[] tasks = ArrayPool <Task <object?> > .Shared.Rent(list.Items.Count);

            var result = new object?[list.Items.Count];

            try
            {
                for (var i = 0; i < list.Items.Count; i++)
                {
                    context.RequestAborted.ThrowIfCancellationRequested();

                    // it is guaranteed that this is always a string literal.
                    StringValueNode nodeId         = (StringValueNode)list.Items[i];
                    IdValue         deserializedId = serializer.Deserialize(nodeId.Value);
                    NameString      typeName       = deserializedId.TypeName;

                    context.SetLocalValue(NodeId, nodeId.Value);
                    context.SetLocalValue(InternalId, deserializedId.Value);
                    context.SetLocalValue(InternalType, typeName);
                    context.SetLocalValue(WellKnownContextData.IdValue, deserializedId);

                    tasks[i] =
                        context.Schema.TryGetType <ObjectType>(typeName, out ObjectType? type) &&
                        type.ContextData.TryGetValue(NodeResolver, out var o) &&
                        o is FieldResolverDelegate resolver
                            ? resolver.Invoke(context).AsTask()
                            : _nullTask;
                }

                for (var i = 0; i < list.Items.Count; i++)
                {
                    context.RequestAborted.ThrowIfCancellationRequested();

                    Task <object?> task = tasks[i];
                    if (task.IsCompleted)
                    {
                        if (task.Exception is null)
                        {
                            result[i] = task.Result;
                        }
                        else
                        {
                            result[i] = null;
                            ReportError(context, i, task.Exception);
                        }
                    }
                    else
                    {
                        try
                        {
                            result[i] = await task;
                        }
                        catch (Exception ex)
                        {
                            result[i] = null;
                            ReportError(context, i, ex);
                        }
                    }
                }

                return(result);
            }
            finally
            {
                ArrayPool <Task <object?> > .Shared.Return(tasks);
            }
        }
        else
        {
            var result = new object?[1];
            result[0] = await ResolveSingleNode(context, serializer, Ids);

            return(result);
        }
    }
コード例 #12
0
        public object?OnAfterDeserialize(object?runtimeValue)
        {
            if (runtimeValue is null)
            {
                return(null);
            }

            if (runtimeValue is IdValue id &&
                (!_validateType || _typeName.Equals(id.TypeName)))
            {
                return(id.Value);
            }

            if (runtimeValue is string s)
            {
                try
                {
                    id = _idSerializer.Deserialize(s);

                    if (!_validateType || _typeName.Equals(id.TypeName))
                    {
                        return(id.Value);
                    }
                }
                catch
                {
                    throw new GraphQLException(
                              ErrorBuilder.New()
                              .SetMessage("The ID `{0}` has an invalid format.", s)
                              .Build());
                }

                throw new GraphQLException(
                          ErrorBuilder.New()
                          .SetMessage("The ID `{0}` is not an ID of `{1}`.", s, _typeName)
                          .Build());
            }

            if (runtimeValue is IEnumerable <IdValue> idEnumerable)
            {
                IList list = _createList();

                foreach (IdValue idv in idEnumerable)
                {
                    if (!_validateType || _typeName.Equals(idv.TypeName))
                    {
                        list.Add(idv.Value);
                    }
                }

                return(list);
            }

            if (runtimeValue is IEnumerable <string> stringEnumerable)
            {
                try
                {
                    IList list = _createList();

                    foreach (string sv in stringEnumerable)
                    {
                        id = _idSerializer.Deserialize(sv);

                        if (!_validateType || _typeName.Equals(id.TypeName))
                        {
                            list.Add(id.Value);
                        }
                    }

                    return(list);
                }
                catch
                {
                    throw new GraphQLException(
                              ErrorBuilder.New()
                              .SetMessage(
                                  "The IDs `{0}` have an invalid format.",
                                  string.Join(", ", stringEnumerable))
                              .Build());
                }
            }

            throw new GraphQLException(
                      ErrorBuilder.New()
                      .SetMessage("The specified value is not a valid ID value.")
                      .Build());
        }
コード例 #13
0
    public object?OnAfterDeserialize(object?runtimeValue)
    {
        if (runtimeValue is null)
        {
            return(null);
        }

        if (runtimeValue is IdValue id)
        {
            return(id.Value);
        }

        if (runtimeValue is string s)
        {
            try
            {
                return(_idSerializer.Deserialize(s).Value);
            }
            catch
            {
                throw new GraphQLException(
                          ErrorBuilder.New()
                          .SetMessage("The ID `{0}` has an invalid format.", s)
                          .Build());
            }
        }

        if (runtimeValue is IEnumerable <IdValue?> nullableIdEnumerable)
        {
            List <object?> list = new();
            foreach (IdValue?idv in nullableIdEnumerable)
            {
                if (!idv.HasValue)
                {
                    list.Add(null);
                }
                else
                {
                    list.Add(idv.Value.Value);
                }
            }

            return(list);
        }

        if (runtimeValue is IEnumerable <IdValue> idEnumerable)
        {
            List <object?> list = new();

            foreach (IdValue idv in idEnumerable)
            {
                list.Add(idv.Value);
            }

            return(list);
        }

        if (runtimeValue is IEnumerable <string?> stringEnumerable)
        {
            try
            {
                List <object?> list = new();

                foreach (string?sv in stringEnumerable)
                {
                    if (sv is null)
                    {
                        list.Add(null);
                        continue;
                    }

                    id = _idSerializer.Deserialize(sv);

                    list.Add(id.Value);
                }

                return(list);
            }
            catch
            {
                throw new GraphQLException(
                          ErrorBuilder.New()
                          .SetMessage(
                              "The IDs `{0}` have an invalid format.",
                              string.Join(", ", stringEnumerable))
                          .Build());
            }
        }

        throw new GraphQLException(
                  ErrorBuilder.New()
                  .SetMessage("The specified value is not a valid ID value.")
                  .Build());
    }