PHPackages                             maiscraft/graphql - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. maiscraft/graphql

ActiveLibrary[API Development](/categories/api)

maiscraft/graphql
=================

PHP 8 Attribute + Reflection driven GraphQL Schema auto-generation engine. Framework-agnostic, with strategy pattern type conversion and container DI.

1.0.0(1mo ago)001MITPHP ^8.2

Since Jun 21Compare

[ Source](https://github.com/mslbit/graphql)[ Packagist](https://packagist.org/packages/maiscraft/graphql)[ Docs](https://github.com/mslbit/graphql)[ RSS](/packages/maiscraft-graphql/feed)WikiDiscussions Synced 2w ago

READMEChangelogDependencies (4)Versions (2)Used By (1)

Maiscraft GraphQL
=================

[](#maiscraft-graphql)

基于 PHP 8 Attribute + 反射的 GraphQL Schema 自动生成引擎，框架无关。

核心理念
----

[](#核心理念)

- **约定优于配置**：getter/setter/构造函数自动推导字段，无需手动注册
- **最小注解设计**：`#[Type]`、`#[Field]`、`#[Query]`、`#[Mutation]`、`#[Arg]` 五个注解
- **反射驱动**：PHP 反射自动生成 Schema，减少样板代码
- **策略模式 + 容器注入**：TypeResolver（唯一决策点）→ TypeConverterFactory → 各 TypeConverter，核心服务通过容器单例

架构
--

[](#架构)

```
Driver（组装容器，注册核心服务）
  └─ TypeResolver（唯一决策点 + 唯一注册入口）
       ├─ enum_exists / class_exists 判断收敛于此
       ├─ TypeKind 分类（SCALAR / ENUM / OBJECT / INPUT_OBJECT）
       └─ TypeConverterFactory → EnumTypeConverter / ObjectTypeConverter / InputTypeConverter
  └─ TypeRegistry（纯存储，零判断）
  └─ PhpTypeMapper（PHP → GraphQL 类型映射）
  └─ RootFieldConverter（Query/Mutation 根字段 + 运行时值转换）

```

**职责边界：**

- **TypeResolver**：唯一决策点，所有类型判断收敛到这里
- **TypeRegistry**：纯存储，只做 get/set/has/mapClassName
- **Converter**：纯转换，className → GraphQL Type，零注册逻辑
- **所有核心服务通过 ContainerInterface 注入，保证单例**

安装
--

[](#安装)

```
composer require maiscraft/graphql
composer require maiscraft/graphql-hyperf  # Hyperf 框架适配
```

快速开始
----

[](#快速开始)

### 1. 定义 Entity（Output Type）

[](#1-定义-entityoutput-type)

```
namespace App\Domain\Entity;

use Maiscraft\GraphQL\Annotation\Type;
use Maiscraft\GraphQL\Annotation\Field;

#[Type(description: '文章')]
class Article
{
    public function __construct(
        private readonly ?int $id = null,
        private readonly string $title = '',
        private readonly string $slug = '',
        private readonly string $status = 'draft',
    ) {}

    #[Field(type: 'ID')]
    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): string
    {
        return $this->title;
    }

    public function getSlug(): string
    {
        return $this->slug;
    }

    // is* 方法 → is_fieldname 布尔字段
    public function isPublished(): bool
    {
        return $this->status === 'published';
    }
}
```

**字段暴露规则：**

来源OutputInput构造函数参数✅ 自动收集✅ 自动收集`get*` 方法✅ 自动收集❌`is*` 方法✅ → `is_fieldname`❌`set*` 方法❌✅ 自动收集public 属性仅 `#[Field]` 标注仅 `#[Field]` 标注`#[Field(hidden: true)]`❌ 不输出❌ 不输出### 2. 定义 Enum

[](#2-定义-enum)

```
namespace App\Domain\ValueObject;

use Maiscraft\GraphQL\Annotation\Type;

#[Type(description: '发布状态')]
enum PublishStatus
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
}
```

支持 backed enum 和非 backed enum，运行时值转换统一通过 `ReflectionEnum::getCase()` 反射获取，无硬编码方法依赖。

### 3. 定义 DTO（Input Type）

[](#3-定义-dtoinput-type)

```
namespace App\DTO;

class CreateArticleDTO
{
    public function __construct(
        public readonly string $title,
        public readonly string $slug,
        public readonly ?string $description = null,
    ) {}
}
```

构造函数参数自动成为 GraphQL Input 字段，运行时通过反射构造实例（snake\_case → camelCase 自动映射）。

### 4. 定义 Resolver

[](#4-定义-resolver)

```
namespace App\GraphQL;

use App\Domain\Entity\Article;
use App\DTO\CreateArticleDTO;
use Maiscraft\GraphQL\Annotation\Query;
use Maiscraft\GraphQL\Annotation\Mutation;
use Maiscraft\GraphQL\Annotation\Arg;
use Maiscraft\GraphQL\Contract\ResolverInterface;

class ArticleResolver implements ResolverInterface
{
    public function __construct(
        private ArticleRepositoryInterface $repository
    ) {}

    #[Query(description: 'Get an article by ID')]
    public function article(#[Arg(type: 'ID!')] string $id): ?Article
    {
        return $this->repository->findById((int) $id);
    }

    #[Query(description: 'Get paginated articles')]
    public function articles(?int $page = null, ?int $pageSize = null): ArticlePaginator
    {
        return $this->repository->paginate($page ?? 1, $pageSize ?? 10);
    }

    #[Mutation(description: 'Create a new article')]
    public function createArticle(CreateArticleDTO $input): Article
    {
        return $this->repository->save(new Article(
            title: $input->title,
            slug: $input->slug,
            description: $input->description,
        ));
    }

    #[Mutation(description: 'Delete an article')]
    public function deleteArticle(#[Arg(type: 'ID!')] string $id): bool
    {
        return $this->repository->delete((int) $id);
    }
}
```

### 5. 配置（Hyperf）

[](#5-配置hyperf)

```
// config/autoload/graphql.php
return [
    'debug' => true,

    // 目录路径扫描（从文件内容解析 namespace 获取类名）
    'scan_paths' => [
        BASE_PATH . '/app',
    ],

    'security' => [
        'max_query_depth' => 15,
        'max_query_complexity' => 1000,
    ],
];
```

### 6. 独立使用（无框架）

[](#6-独立使用无框架)

```
use Maiscraft\GraphQL\Default\SimpleContainer;
use Maiscraft\GraphQL\Driver\Driver;

$container = new SimpleContainer();
$driver = new Driver($container);

$schema = $driver->buildSchema(
    resolvers: [ArticleResolver::class],
    types: [Article::class, PublishStatus::class],
);

$result = \GraphQL\GraphQL::executeQuery(
    schema: $schema,
    source: '{ articles { items { id title } total } }',
);
```

### 7. 查询示例

[](#7-查询示例)

```
query {
  article(id: "1") {
    id
    title
    slug
    is_published
  }

  articles(page: 1, pageSize: 10) {
    items {
      id
      title
    }
    total
  }
}
```

```
mutation {
  createArticle(input: {
    title: "新文章"
    slug: "new-article"
    description: "描述"
  }) {
    id
    title
  }
}
```

注解参考
----

[](#注解参考)

### `#[Type]` — 类级别，标记 GraphQL 类型

[](#type--类级别标记-graphql-类型)

```
#[Type(name: 'CustomName', description: '描述', hidden: false)]
```

属性类型默认值说明`name`string类名GraphQL type 名称`description`string`''`类型描述`hidden`bool`false`隐藏，不生成 Schema### `#[Field]` — 方法/属性/参数，标记字段

[](#field--方法属性参数标记字段)

```
#[Field(type: 'ID', description: '描述', hidden: false)]
```

属性类型默认值说明`type`string自动推导GraphQL 类型（支持 `Article[]`、`ID!`、`JSON`）`description`string`null`字段描述`hidden`bool`false`隐藏，不输出到 Schema### `#[Query]` / `#[Mutation]` — 方法，定义根字段

[](#query--mutation--方法定义根字段)

```
#[Query(description: '描述', type: 'ArticlePaginator')]
```

属性类型默认值说明`name`string方法名字段名`description`string`''`字段描述`type`string返回类型推导返回类型名### `#[Arg]` — 参数，定义字段参数

[](#arg--参数定义字段参数)

```
#[Arg(type: 'ID!')]
```

项目结构
----

[](#项目结构)

```
graphql/src/
├── Annotation/           # 注解定义
│   ├── Arg.php
│   ├── Field.php
│   ├── Mutation.php
│   ├── Query.php
│   └── Type.php
├── Contract/             # 接口契约
│   ├── ContainerInterface.php
│   ├── ResolverInterface.php
│   └── ...
├── Converter/            # 类型转换器（策略模式）
│   ├── TypeConverterInterface.php
│   ├── TypeConverterFactory.php
│   ├── EnumTypeConverter.php
│   ├── ObjectTypeConverter.php
│   ├── InputTypeConverter.php
│   └── RootFieldConverter.php
├── Default/              # 默认实现
│   ├── SimpleContainer.php
│   └── ...
├── Driver/               # 驱动层
│   ├── ClassScanner.php
│   └── Driver.php
├── Engine/               # 引擎
│   ├── EngineConfig.php
│   └── GraphQLEngine.php
├── Mapper/               # 类型映射
│   └── PhpTypeMapper.php
├── Metadata/             # 元数据检查
│   └── MetadataInspector.php
├── Type/
│   └── JsonType.php      # JSON 标量类型
├── ReflectionHelper.php  # 共享工具 trait
├── TypeKind.php          # 类型分类枚举
├── TypeRegistry.php      # 纯存储
└── TypeResolver.php      # 唯一决策点 + 唯一注册入口

```

API 端点
------

[](#api-端点)

方法路径说明POST`/graphql`执行 GraphQL 查询GET`/graphql`Introspection 查询GET`/playground`GraphQL Playground 调试界面

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/23d2c2d4840594d8f9e145b55384df97d32e8a25e301fc767e924ec3901edd84?d=identicon)[mslbit](/maintainers/mslbit)

---

Tags

middlewarePSR-11schemaenumgraphqlreflectionannotationphp8attribute

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/maiscraft-graphql/health.svg)

```
[![Health](https://phpackages.com/badges/maiscraft-graphql/health.svg)](https://phpackages.com/packages/maiscraft-graphql)
```

###  Alternatives

[api-platform/core

Build a fully-featured hypermedia or GraphQL API in minutes!

2.6k52.2M366](/packages/api-platform-core)[nuwave/lighthouse

A framework for serving GraphQL from Laravel

3.5k12.2M124](/packages/nuwave-lighthouse)[thecodingmachine/graphqlite

Write your GraphQL queries in simple to write controllers (using webonyx/graphql-php).

5753.4M49](/packages/thecodingmachine-graphqlite)[api-platform/state

API Platform state interfaces

275.4M156](/packages/api-platform-state)[aimeos/ai-admin-graphql

Aimeos Admin GraphQL API extension

1.0k110.7k7](/packages/aimeos-ai-admin-graphql)[jerowork/graphql-attribute-schema

Build your GraphQL schema for webonyx/graphql-php using PHP attributes instead of array-based configuration.

1942.2k](/packages/jerowork-graphql-attribute-schema)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
