Drupal 8.x + GraphQL模块自定义类型/字段插件接收错误“字段必须是以字段名称作为键的对象”

时间:2018-10-04 19:14:23

标签: drupal graphql drupal-modules php-7 drupal-8

我正在尝试创建一个模块,该模块定义其自己的自定义Type和关联的Field插件。

安装后,GraphQLi在控制台中报告以下错误:

未捕获的错误:CustomTypeInterface字段必须是以字段名称作为键的对象,或者是返回此类对象的函数。

Drupal 8.61。我已经尝试了GraphQL 3.0-RC2和3.x-Dev。任何帮助将非常感激。谢谢。

我的代码如下:

/graphql_custom.info.yml

name: GraphQL Custom Type Example
type: module
description: ''
package: GraphQL
core: 8.x
dependencies:
  - graphql_core

/src/CustomObject.php

namespace Drupal\graphql_custom;

class CustomObject {
    protected $data;

    function __construct(String $data) {
        $this->data = $data;
    }

    function getData() {
        return $this->data;
    }
}

/src/Plugin/GraphQL/Fields/CustomField.php

<?php

namespace Drupal\graphql_custom\Plugin\GraphQL\Fields;

use Drupal\graphql_custom\CustomObject;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\graphql\GraphQL\Execution\ResolveContext;
use Drupal\graphql\Plugin\GraphQL\Fields\FieldPluginBase;
use GraphQL\Type\Definition\ResolveInfo;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Created Custom Object with argument as data.
 *
 * @GraphQLField(
 *   id = "custom_field",
 *   secure = true,
 *   name = "customfield",
 *   type = "CustomType",
 *   nullable = true,
 *   arguments = {
 *     "argument" = "String!"
 *   }
 * )
 */
class CustomField extends FieldPluginBase implements ContainerFactoryPluginInterface {
    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        return new static(
            $configuration,
            $plugin_id,
            $plugin_definition
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function isLanguageAwareField() {
        return FALSE;
    }

    /**
     * {@inheritdoc}
     */
    public function resolve($value, array $args, ResolveContext $context, ResolveInfo $info) {
        return parent::resolve($value, $args, $context, $info);
    }

    /**
     * {@inheritdoc}
     */
    public function resolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
        $arg = $args['argument'];
        $object = new CustomObject($arg);

        yield $object;
    }
}

/src/Plugin/GraphQL/Fields/CustomFieldData.php

<?php

namespace Drupal\graphql_custom\Plugin\GraphQL\Fields;

use Drupal\graphql_custom\CustomObject;
use Drupal\graphql\Plugin\GraphQL\Fields\FieldPluginBase;
use Drupal\graphql\GraphQL\Execution\ResolveContext;
use GraphQL\Type\Definition\ResolveInfo;

/**
 * Custom Type Data Field
 *
 * @GraphQLField(
 *   id = "custom_field_data",
 *   secure = true,
 *   name = "data",
 *   type = "String",
 *   parents = {"CustomType"}
 * )
 */

class CustomFieldData extends FieldPluginBase {
    /**
     * {@inheritdoc}
     */
    protected function resolveValues($value, array $args, $context, $info) {
        if ($value instanceOf CustomObject) {
            yield (string) $value->getData();
        } else {
            yield (string) "Empty";
        }
    }
}

/src/Plugin/GraphQL/Interfaces/CustomTypeInterface.php

<?php

namespace Drupal\graphql_custom\Plugin\GraphQL\Interfaces;

use Drupal\graphql_custom\CustomObject;
use Drupal\graphql\Annotation\GraphQLInterface;
use Drupal\graphql\Plugin\GraphQL\Interfaces\InterfacePluginBase;

/**
 * Interface for Custom Type.
 *
 * For simplicity reasons, this example does not utilize dependency injection.
 *
 * @GraphQLInterface(
 *   id = "custom_type_interface",
 *   name = "CustomTypeInterface"
 * )
 */

class CustomTypeInterface extends InterfacePluginBase {
    /**
     * {@inheritdoc}
     */
    public function resolveType($object) {
        if ($object instanceof CustomObject) {
            $schemaManager = \Drupal::service('graphql_core.schema_manager');

            return $schemaManager->findByName('CustomType', [
                    GRAPHQL_CORE_TYPE_PLUGIN,
                ]);
        }
    }
}

/src/Plugin/GraphQL/Types/CustomType.php

<?php
namespace Drupal\graphql_custom\Plugin\GraphQL\Types;

use Drupal\graphql_custom\CustomObject;
use Drupal\graphql\Plugin\GraphQL\Types\TypePluginBase;
use Drupal\graphql\GraphQL\Execution\ResolveContext;
use GraphQL\Type\Definition\ResolveInfo;

/**
 * GraphQL Custom Type.
 *
 * @GraphQLType(
 *   id = "custom_type",
 *   name = "CustomType",
 *   interfaces = {"CustomTypeInterface"}
 * )
 */

class CustomType extends TypePluginBase {
    /**
     * {@inheritdoc}
     */
    public function applies($object, ResolveContext $context, ResolveInfo $info) {
        return $object instanceof CustomObject;
    }
}

1 个答案:

答案 0 :(得分:0)

对于字段,您应该在父级中使用接口引用,而不是类型:

parents = {"CustomTypeInterface"}

另一种方法是删除接口并使用示例中提到的直接类型引用。