Schema

未匹配的标注

Schema 定义

Schema 是你类型层次结构的容器,它接受构造函数中的根类型并向内部 GrahpQL 工具提供接收你的类型信息的方法。

graphql-php 中,Schema 是 GraphQL\Type\Schema 的一个实例,它的构造函数接受数组形式的配置:

<?php
use GraphQL\Type\Schema;

$schema = new Schema([
    'query' => $queryType, 
    'mutation' => $mutationType,
]);

参见 下面 可用的构造函数选项。

Query 和 Mutation 类型

GraphQL Schema 包含两种基础类型:

  • Query 类型是 API 读取的呈现
  • Mutation 类型 (可选的) 通过在应用中声明所有可能的变更来公开编写API。

Query 和 Mutation 类型 对象类型 是 API 中包含的常规基础字段:

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'hello' => [
            'type' => Type::string(),
            'resolve' => function() {
                return 'Hello World!';
            }
        ],
        'hero' => [
            'type' => $characterInterface,
            'args' => [
                'episode' => [
                    'type' => $episodeEnum
                ]
            ],
            'resolve' => function ($rootValue, $args) {
                return StarWarsData::getHero(isset($args['episode']) ? $args['episode'] : null);
            },
        ]
    ]
]);

$mutationType = new ObjectType([
    'name' => 'Mutation',
    'fields' => [
        'createReview' => [
            'type' => $createReviewOutput,
            'args' => [
                'episode' => $episodeEnum,
                'review' => $reviewInputObject
            ],
            'resolve' => function($val, $args) {
                // 计划描述
            }
        ]
    ]
]);

请记住,除了声明 API 覆盖范围的特殊含义之外,那些类型与其他类型 对象类型 是相同的,并且他们的字段作用也是完全相同的。

Mutation 类型也只是常规对象类型, 区别主要是在语义上。
Mutation 类型字段的名称通常是动词,并且他们几乎总是带有参数,时常是比较复杂的输入值 (详阅 变更和输入类型)。

配置选项

GraphQL Schema 构造函数需要 GraphQL\Type\SchemaConfig 的实例或
包含以下选项的数组:

Option Type Notes
query ObjectType 必须。 读取 API 中包含根级字段的对象类型 (通常命名为 "Query")
mutation ObjectType 写入 API 中包含根级字段的对象类型 (通常命名为 "Mutation")
subscription ObjectType 保留用于将来的描述实现。目前表现为 graphql-js 自检查询的兼容,用于各种客户端 (如 Relay 或 GraphiQL)
directives Directive[] schema 支持的完整 指令 列表。 默认包含内建指令 @skip@include

如果你传递自定义指令并且依然想使用内建指令,请声明添加它们。例如:

array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]);
types ObjectType[] 对象类型类表,它在静态 schema 解析期间是不能被 graphql-php 发现的。

大多数情况下,对象类型未曾在字段中被直接引用,但它依然是 schema 的一部分时会用到,因为它实现了一个在 resolveType 中调用解析为此对象类型的接口。

请注意,您在此处无需传递所有类型 ,它只是具体用例的解决方法。
typeLoader callable function($name) 返回给定的类型实例名称。 多次调用情况下,必须返回同样的实例。 查阅下文延迟类型加载部分。

使用配置类

如果你更喜欢在 IDE 中使用自动完成和静态时间验证的流式接口进行配置,使用 GraphQL\Type\SchemaConfig 来替代数组形式:

<?php
use GraphQL\Type\SchemaConfig;
use GraphQL\Type\Schema;

$config = SchemaConfig::create()
    ->setQuery($myQueryType)
    ->setTypeLoader($myTypeLoader);

$schema = new Schema($config);

懒加载类型

默认情况下, Schema 会扫描你的所有类型,字段和参数提供给 GraphQL 的查询. 当 Schema 有许多类型时,他可能会导致性能上的开销.

这种情况下,建议通过 typeLoader(懒加载) 选项传递给 schema 构造器 并将所有的 fields(字段) 定义为回调.

类型加载的概念与PHP类加载非常相似,但是请记住 typeLoader(类型加载) 必须始终返回类型相同的实例.

使用例子:

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Schema;

class Types
{
    private $types = [];

    public function get($name)
    {
        if (!isset($this->types[$name])) {
            $this->types[$name] = $this->{$name}();
        }
        return $this->types[$name];
    }

    private function MyTypeA()
    {
        return new ObjectType([
            'name' => 'MyTypeA',
            'fields' => function() {
                return [
                    'b' => ['type' => $this->get('MyTypeB')]
                ];
            }
        ]);
    }

    private function MyTypeB()
    {
        // ...
    }
}

$registry = new Types();

$schema = new Schema([
    'query' => $registry->get('Query'),
    'typeLoader' => function($name) use ($registry) {
        return $registry->get($name);
    }
]);

Schema 的验证

默认情况下, Schema 是在类型和字段简单验证下定义创建的
(因为验证需要完整的schema扫描并且在大的schema下,代价会变的非常大)。

但是有一个特殊的方法 assertValid() 在schema实例中抛出 GraphQL\Error\InvariantViolation 当遇到任何异常错误时, 比如:

  • 类型/参数的使用无效
  • 缺少接口的实现
  • 接口的实现无效
  • 其他schema的错误...

Schema 验证应该在 CLI 命令或者在编译你的项目中使用.
绝对不要在生产环境中调用 web 请求。

使用例子:

<?php
try {
    $schema = new GraphQL\Type\Schema([
        'query' => $myQueryType
    ]);
    $schema->assertValid();
} catch (GraphQL\Error\InvariantViolation $e) {
    echo $e->getMessage();
}

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/graphql-php/typ...

译文地址:https://learnku.com/docs/graphql-php/typ...

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
贡献者:5
讨论数量: 0
发起讨论 查看所有版本


暂无话题~