Mutations 和 Input Types

未匹配的标注

变更

变更只是字段的常规 对象类型 带了参数。
对于运行中的 GraphQL PHP 来说,带参数的查询字段和变更是没有区别的。
他们几乎是同时进行的 facebook GraphQL 版本
延伸地来说,变更只是 GraphQL 中的特殊场景。

下面是变更操作的示例:

mutation CreateReviewForEpisode($ep: EpisodeInput!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

为了执行这个变更,你需要使用 Mutation 类型 在 Schema 定义的时候

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

$myMutationType = new ObjectType([
    'name' => 'Mutation',
    'fields' => [
        // 变更列表:
        'createReview' => [
            'args' => [
                'episode' => Type::nonNull($episodeInputType),
                'review' => Type::nonNull($reviewInputType)
            ],
            'type' => new ObjectType([
                'name' => 'CreateReviewOutput',
                'fields' => [
                    'stars' => ['type' => Type::int()],
                    'commentary' => ['type' => Type::string()]
                ]
            ]),
        ],
        // ... other mutations
    ]
]);

如你所见,变更与常规对象类型的唯一区别是命名语义的不同(动词 vs 名词)。

我们看到了参数也可以是复杂类型的。所以,为了最大程度发挥变更(也包括常规字段参数)的作用,我们必须学会:如何构造复杂输入类型。

关于输入和输出类型

所有 GraphQL 中的类型都包含两种类型:输入输出

显然, 非空 和 列表 类型也属于这两个类别,具体取决于它们的内部类型 。

到目前为止该文档中的所有字段 参数 示例都是 标量 或者
枚举 类型。但是你也可以传递更为复杂的对象。

这在有变化的情况下是相当有价值的,因为输入的数据可能相当复杂。

输入对象类型

GraphQL 规范为复杂输入定义了输入对象类型。这与对象类型很相似,但是它的字段没有 argsresolve 选项,并且它们的 type 必须是输入类型。

在 graphql-php 中 Input Object TypeGraphQL\Type\Definition\InputObjectType
(或它的某个子类) 的实例,GraphQL\Type\Definition\InputObjectType 在构造器中接收数组配置参数:

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

$filters = new InputObjectType([
    'name' => 'StoryFiltersInput',
    'fields' => [
        'author' => [
            'type' => Type::id(),
            'description' => 'Only show stories with this author id'
        ],
        'popular' => [
            'type' => Type::boolean(),
            'description' => 'Only show popular stories (liked by several people)'
        ],
        'tags' => [
            'type' => Type::listOf(Type::string()),
            'description' => 'Only show stories which contain all of those tags'
        ]
    ]
]);

每个字段都可能是其他的输入对象类型(这为复杂的输入层次结构提供了可能)。

配置说明

输入对象类型构造器接收数组参数只包含 3 个选项:

Option Type Notes
name string 必须。 Schema 内当前对象类型的唯一名称
fields array or callable 必须。 描述对象字段的数组或返回该类型数组的回调函数(查看下文)
description string 呈现于客户端的当前类型文本说明(例如:GraphiQL 用于自动生成文档)

任一字段数组包含以下几条内容:

Option Type Notes
name string 必须。 输入字段名称。 为空时,使用 fields 数组键值
type Type 必须。 输入类型Scalar, Enum, InputObjectType + 其中任意组合及 nonNulllistOf 修改器)的实例
description string 呈现于客户端的输入字段文本说明 (例如:GraphiQL 用于自动生成文档)
defaultValue scalar 当前输入字段的默认值

运用输入类型

在上面的例子中我们定义了输入对象类型。现在我们就在其中的一个字段的参数中运用一下:

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

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'stories' => [
            'type' => Type::listOf($storyType),
            'args' => [
                'filters' => [
                    'type' => Type::nonNull($filters),
                    'defaultValue' => [
                        'popular' => true
                    ]
                ]
            ],
            'resolve' => function($rootValue, $args) {
                return DataSource::filterStories($args['filters']);
            }
        ]
    ]
]);

(注意,你可以给复杂的输入类型定义 默认值作为关联数组)。

然后 GraphQL 查询是可以指定固定值去过滤的:

{
    stories(filters: {author: "1", popular: false})
}

或者作为查询变量:

query($filters: StoryFiltersInput!) {
    stories(filters: $filters)
}
$variables = [
    'filters' => [
        "author" => "1",
        "popular" => false
    ]
];

graphql-php 将根据您的输入对象类型验证输入,并且作为 $args['filters'] 传给你的解析器

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

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

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

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

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:6
讨论数量: 0
发起讨论 只看当前版本


暂无话题~