infinityloop-dev/graphpinator-nette

Graphpinator 为 Nette 框架提供的适配器和插件。

v1.4.1 2024-04-04 10:00 UTC

This package is auto-updated.

Last update: 2024-09-04 11:02:45 UTC


README

⚡🌐⚡ Graphpinator 为 Nette 框架提供的适配器和插件。

简介

本软件包包含适配器和工具,可轻松将 Graphpinator 集成到 Nette 应用程序中。

安装

使用 composer 安装包

composer require infinityloop-dev/graphpinator-nette

如何使用

ApiPresenter

用于执行针对给定模式的 GraphQL API 请求的 presenter 的简单版本。它可以扩展以改变其功能(例如,通过覆盖 getEnabledModules 函数)或作为在您自己的 presenter 中包含功能的灵感。

通过创建路由来启用 presenter

$router[] = new Route('/', [
    'module' => 'Graphpinator',
    'presenter' => 'Api',
]);

您还需要将模块与 presenter 注册以映射到正确的命名空间。

application:
    mapping:
        Graphpinator: 'Graphpinator\Nette\*Presenter'

需要在您的 DI 容器中提供 SchemaNetteCache 服务,以便将其注入到 presenter 中。

# Automatically find and register all types and directives located in `GraphQl` namespace as services
search:
    graphql:
        in: '%appDir%/GraphQL'
        extends:
            - Graphpinator\Typesystem\Contract\NamedType
            - Graphpinator\Typesystem\Contract\Directive
services:
    # Register a NetteCache adapter
    - Graphpinator\Nette\NetteCache

    # The SimpleContainer is a container of GraphQL types
    # It is automatically injected by all types and directives as Nette automatically detects a typehint in SimpleContainers contructor
    - Graphpinator\SimpleContainer

    # Any additional types must be also registred to become available in the type container
    - Graphpinator\ExtraTypes\EmailAddressType
    - Graphpinator\ExtraTypes\PhoneNumberType

    # Register a Schema
    - Graphpinator\Typesystem\Schema(
        @Graphpinator\SimpleContainer, # Container of types
        @App\GraphQL\Query, # Query type
        null, # Mutation type
        null # Subscription type
    )

   # Alternativelly you may use the named service and add a setup to the Schema service
   schema.public:
        factory: Graphpinator\Typesystem\Schema(
            @Graphpinator\SimpleContainer,
            @App\GraphQL\Query,
            @App\GraphQL\Mutation,
            null
        )
        setup:
            - setDescription("""
            My GraphQL API
            """)

SchemaPresenter

Schema presenter 包含两个动作。

  • actionHtml,用于渲染 HTML 页面
  • actionFile,用于渲染文本文件 - 文件作为附件发送到浏览器,告诉浏览器显示下载提示

可以通过 Router 启用动作,以下是在 /schema.graphql 路径上启用 HTML 动作的示例。

$router[] = new Route('/schema.graphql',
    'module' => 'Graphpinator',
    'presenter' => 'Schema',         
    'action' => 'html',
]);

GraphiQLPresenter

包含 GraphiQL 的 presenter,GraphiQL 是与您的模式交互的图形界面。

通过创建路由来启用 presenter

$router[] = new Route('/graphiql',
    'module' => 'Graphpinator',
    'presenter' => 'GraphiQl',         
    'action' => 'default',
]);

还需要传递您的 API 端点的位置,GraphiQL 将连接到该端点。

services:
    - Graphpinator\Nette\GraphiQlPresenter(':Api:Graphql:default')

循环依赖关系

当使用抽象类型时,必须使用访问器避免循环依赖关系。Nette 通过自动为访问器接口提供实现来简化这一点,该实现使用简单的 DI 配置。

interface SlideAccessor
{
    public function getSlideSingle() : SlideSingle;

    public function getSlideDouble() : SlideDouble;

    public function getSlideTriple() : SlideTriple;
}
services:
    - SlideAccessor(
        slideSingle: @SlideSingle
        slideDouble: @SlideDouble
        slideTriple: @SlideTriple
    )

然后,将此接口注入到抽象类型中,而不是具体类型,以打破依赖循环。

多个模式

一些更复杂的应用程序可能需要托管具有不同目的的多个不同的 GraphQL 模式。为了做到这一点,我们需要在配置 DI 时采用不同的方法。

# Search and register all the types in directives in a given namespace - and also append a tag to those services
search:
    graphqlPublicTypes:
        in: '%appDir%/GraphQL/Public'
        extends:
            - Graphpinator\Typesystem\Contract\NamedType
        tags:
            - graphql.public.types
    graphqlPublicDirectives:
        in: '%appDir%/GraphQL/Public'
        extends:
            - Graphpinator\Typesystem\Contract\Directive
        tags:
            - graphql.public.directives
services:
    # Register a container and inject services with a tag
    publicContainer:
        factory: Graphpinator\SimpleContainer(
            tagged( graphql.public.types )
            tagged( graphql.public.directives )
        )
    # Register a Schema using a container with the correct set of types
    - App\GraphQL\Public\Schema(@publicContainer)

建议为每个 Schema 使用单独的类,以便它可以轻松注册为单独的服务并注入到 presenter 中。

<?php declare(strict_types = 1);

namespace App\GraphQL\Public;

final class Schema extends \Graphpinator\Typesystem\Schema
{
    public function __construct(\Graphpiantor\SimpleContainer $container)
    {
        parent::__construct($container, $container->getType('Query'), $container->getType('Mutation'));

        $this->setDescription('My GraphQL API');
    }
}

适配器

  • \Graphpinator\Nette\TracyLogger
    • 实现了 \Graphpinator\Graphpinator 中的日志记录接口。
  • \Graphpinator\Nette\NetteRequestFactory
    • 实现了 RequestFactory,并使从 Nette HTTP 抽象直接创建 \Graphpinator\Request\Request 成为可能。
  • \Graphpinator\Nette\FileProvider
    • 实现了 FileProvider 接口,该接口由 infinityloop-dev/graphpinator-upload 模块需要。
  • \Graphpinator\Nette\NetteCache
    • 从 Nette 缓存到 Psr CacheInterface 的适配器,该适配器由 infinityloop-dev/graphpinator-persisted-queries 模块需要。