x-graphql/schema-gateway

将所有子模式合并为一个,并为它们添加关系

0.2.3 2024-04-28 00:21 UTC

This package is auto-updated.

Last update: 2024-08-28 01:02:54 UTC


README

unit tests codecov

Copyright GraphQL Stitching

图片来源: GraphQL Stitching

入门指南

通过 Composer 安装此包

composer require x-graphql/schema-gateway

添加 http-schema 包以在 HTTP 上创建和执行 GraphQL 模式

composer require x-graphql/http-schema

用法

<?php

require __DIR__ . '/vendor/autoload.php';

use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Utils\SchemaPrinter;
use GraphQL\Type\Schema;
use XGraphQL\HttpSchema\HttpDelegator;
use XGraphQL\HttpSchema\HttpSchemaFactory;
use XGraphQL\SchemaGateway\MandatorySelectionSetProviderInterface;
use XGraphQL\SchemaGateway\Relation;
use XGraphQL\SchemaGateway\RelationArgumentResolverInterface;
use XGraphQL\SchemaGateway\RelationOperation;
use XGraphQL\SchemaGateway\SchemaGatewayFactory;
use XGraphQL\SchemaGateway\SubSchema;

$localSchema = new Schema([
    'query' => new ObjectType([
        'name' => 'Query',
        'fields' => [
            'person' => [
                'type' => new ObjectType([
                    'name' => 'Person',
                    'fields' => [
                        'name' => Type::nonNull(Type::string()),
                        'fromCountry' => Type::nonNull(Type::string()),
                    ],

                ]),
                'resolve' => fn() => ['name' => 'John Doe', 'fromCountry' => 'VN']
            ],
        ],
    ]),
]);
$localSubSchema = new SubSchema('local', $localSchema);

$remoteSchema = HttpSchemaFactory::createFromIntrospectionQuery(
    new HttpDelegator('https://countries.trevorblades.com/'),
);
$remoteSubSchema = new SubSchema('remote', $remoteSchema);

$countryRelation = new Relation(
    'Person',
    'remoteCountry',
    RelationOperation::QUERY,
    'country',
    new class implements RelationArgumentResolverInterface, MandatorySelectionSetProviderInterface {
        public function shouldKeep(string $argumentName, Relation $relation): bool
        {
            return false;
        }

        public function resolve(array $objectValue, array $currentArgs, Relation $relation): array
        {
            return ['code' => $objectValue['fromCountry']];
        }

        public function getMandatorySelectionSet(Relation $relation): string
        {
            return '{ fromCountry }';
        }
    }
);

$schemaGateway = SchemaGatewayFactory::create([$localSubSchema, $remoteSubSchema], [$countryRelation]);

$query = <<<'GQL'
query {
  continents {
    name
  }

  person {
    name
    remoteCountry {
      name
      code
    }
  }
}
GQL;

var_dump(SchemaPrinter::doPrint($schemaGateway));
var_dump(GraphQL::executeQuery($schemaGateway, $query)->toArray());

合并子模式时的规则

  • 所有合并模式中的顶级字段名必须是唯一的(区分大小写)。
  • 具有完全相同名称和结构的类型将被合并。但是,具有相同名称但结构不同的类型将导致类型冲突。

灵感

此库受到了许多其他相关工作的启发,包括

感谢所有创建这些项目的人!

致谢

Minh Vuong 创建