知海

PHP:GraphQL by PoP(服务端)

graphql-github-io-zh-Hans生态项目与库

PHP:GraphQL by PoP(服务端)

属性
名称 GraphQL by PoP
描述 基于 PHP 的、与 CMS 无关的 GraphQL 服务器。它遵循 code-first(代码优先)方法,动态生成 schema。
官网 https://graphql-by-pop.com
GitHub leoloso/PoP

GraphQL by PoP 遵循 code-first(代码优先)方法 来生成 schema(可以针对不同的客户端/应用进行定制)。字段会动态地“订阅”到类型上,并可根据上下文决定是否添加到 schema 中。

下面展示了一个 User 类型是如何实现的:

php 复制代码
class UserTypeResolver extends AbstractTypeResolver
{
  public function getTypeName(): string
  {
    return 'User';
  }

  public function getSchemaTypeDescription(): ?string
  {
    $translationAPI = TranslationAPIFacade::getInstance();
    return $translationAPI->__('Representation of a user', 'users');
  }

  public function getID(object $user)
  {
    return $user->ID;
  }

  public function getTypeDataLoaderClass(): string
  {
    return UserTypeDataLoader::class;
  }
}

请注意 TypeResolver 并没有指明它有哪些字段。它也不会从数据库加载对象,而是将此任务委托给 TypeDataLoader

通过 FieldResolver 向类型添加字段:

php 复制代码
class UserFieldResolver extends AbstractDBDataFieldResolver
{
  public static function getClassesToAttachTo(): array
  {
    return [
      UserTypeResolver::class,
    ];
  }

  public static function getFieldNamesToResolve(): array
  {
    return [
      'username',
      'email',
      'url',
    ];
  }

  public function getSchemaFieldDescription(
    TypeResolverInterface $typeResolver,
    string $fieldName
  ): ?string {
    $translationAPI = TranslationAPIFacade::getInstance();
    $descriptions = [
      'username' => $translationAPI->__("User's username handle", "users"),
      'email' => $translationAPI->__("User's email", "users"),
      'url' => $translationAPI->__("URL of the user's profile in the website", "users"),
    ];
    return $descriptions[$fieldName];
  }

  public function getSchemaFieldType(
    TypeResolverInterface $typeResolver,
    string $fieldName
  ): ?string {
    $types = [
      'username' => SchemaDefinition::TYPE_STRING,
      'email' => SchemaDefinition::TYPE_EMAIL,
      'url' => SchemaDefinition::TYPE_URL,
    ];
    return $types[$fieldName];
  }

  public function resolveValue(
    TypeResolverInterface $typeResolver,
    object $user,
    string $fieldName,
    array $fieldArgs = []
  ) {
    switch ($fieldName) {
      case 'username':
        return $user->user_login;

      case 'email':
        return $user->user_email;

      case 'url':
        $userService = UserServiceFacade::getInstance();
        return $userService->getUserProfileURL($user->ID);
    }

    return null;
  }
}

对于 GraphQL schema 中字段的定义及其解析,被拆分到了 FieldResolver 的多个函数中:

  • getSchemaFieldDescription
  • getSchemaFieldType
  • resolveValue
  • getSchemaFieldArgs
  • isSchemaFieldResponseNonNullable
  • getImplementedInterfaceClasses
  • resolveFieldTypeResolverClass
  • resolveFieldMutationResolverClass

与通过单个函数或配置数组实现所有功能相比,这种代码更易读,使得解析器的实现和维护更加容易。

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。