flownative/graphql

Flownative GraphQL

资助包维护!
robertlemke

安装数: 1,057

依赖项: 0

建议者: 0

安全: 0

星标: 2

关注者: 4

分支: 1

开放问题: 0

类型:neos-package

v2.0.0 2024-01-18 08:52 UTC

This package is auto-updated.

Last update: 2024-09-18 10:07:00 UTC


README

MIT license Packagist Maintenance level: Love

Neos Flow 的 GraphQL 库

这个 Flow 包为 webonyx/graphql-php 包提供了一个最小的包装。这个库不是提供大量功能或自动代码分析,它只解决基本必要的任务,不会干扰您与原始 GraphQL 库之间的实现。

示例

以下是一个 Hello-World 示例,它还包含了对 Api 类中提供的进一步查询和突变自动解析的支持

Classes/GraphQL/Api.php:

<?php
declare(strict_types=1);
namespace Flownative\Example\GraphQL;

final class Api
{
    public function ping($_, array $arguments): array
    {
        return [
            'pong' => time()
        ];
    }
}

Resources/Private/GraphQL/schema.graphql:

type Query {
    ping: String
}

Classes/GraphQL/Endpoint.php:

<?php
declare(strict_types=1);
namespace Flownative\Example\GraphQL;

use Flownative\GraphQL\EndpointInterface;
use GraphQL\Executor\ExecutionResult;
use GraphQL\GraphQL;
use GraphQL\Type\Schema;
use Neos\Eel\FlowQuery\OperationResolver;

final class Endpoint implements EndpointInterface
{
    public function __construct(readonly private Api $api)
    {
    }

    public static function getPath(): string
    {
        return '/api/graphql';
    }

    public function getSchemaUri(): string
    {
        return 'resource://Flownative.Example/Private/GraphQL/schema.graphql';
    }

    public function __invoke($objectValue, $args, $_, ResolveInfo $resolveInfo): mixed
    {
        $fieldName = $resolveInfo->fieldName;
        if ($objectValue === null && method_exists($this->api, $fieldName)) {
            $result = $this->api->$fieldName($objectValue, $args);
        } elseif (is_array($objectValue)) {
            $result = $objectValue[$fieldName] ?? null;
        } elseif ($objectValue !== null && method_exists($objectValue, $fieldName)) {
            $result = $objectValue->$fieldName();
        } elseif ($objectValue !== null && method_exists($objectValue, 'get' . ucfirst($fieldName))) {
            $methodName = 'get' . ucfirst($fieldName);
            $result = $objectValue->$methodName($objectValue);
        } elseif ($objectValue !== null && method_exists($objectValue, $fieldName . 'Query')) {
            $methodName = $fieldName . 'Query';
            $query = $objectValue->$methodName();
            if (!$query instanceof Query) {
                throw new RuntimeException(sprintf('Failed to resolve field "%s": %s->%s() returned %s, but expected %s', $fieldName, get_class($objectValue), $methodName, get_debug_type($query), Query::class), 1648713012);
            }
            if (!method_exists($this->api, $query->queryName)) {
                throw new RuntimeException(sprintf('Failed to resolve field "%s": %s->%s() returned %s, but %s->%s() does not exist', $fieldName, get_class($objectValue), $methodName, $query->queryName, get_class($this->api), $query->queryName), 1648713106);
            }
            $result = $this->api->{$query->queryName}(null, $query->arguments);
        } elseif ($objectValue !== null && property_exists($objectValue, $fieldName)) {
            $result = $objectValue->{$fieldName};
        } else {
            throw new RuntimeException(sprintf('Failed to resolve field "%s" on subject %s', $fieldName, get_debug_type($objectValue)), 1613477425);
        }

        if ($result instanceof DateTimeInterface) {
            $result = $result->format(DATE_ISO8601);
        }

        return $result;
    }

    public function getTypeConfigDecorator(): ?callable
    {
        return static function ($typeConfig) {
            $typeConfig['resolveType'] = static function ($object) {
                if (method_exists($object, 'isOfType')) {
                    return $object->isOfType();
                }
                $classname = is_object($object) ? get_class($object) : '';
                if ($position = strrpos($classname, '\\')) {
                    return substr($classname, $position + 1);
                }
                return $position;
            };
            return $typeConfig;
        };
    }
}

致谢和支持

这个库是由 Robert Lemke / Flownative 开发的。欢迎在 GitHub 项目中提出新功能、报告错误或提供错误修复。