lastdragon-ru/lara-asp-graphql
Composer 安装命令:
composer require lastdragon-ru/lara-asp-graphql
包简介
This package provides highly powerful `@searchBy`, `@sortBy`, `@stream` directives for Lighthouse. The `@searchBy` directive provides basic conditions like `=`, `>`, `<`, etc, relations, `not (<condition>)`, enums, and custom operators support. All are strictly typed so you no need to use `Mixed` ty
README 文档
README
This package provides highly powerful @searchBy, @sortBy, @stream directives for lighthouse-php. The @searchBy directive provides basic conditions like =, >, <, etc, relations, not (<condition>), enums, and custom operators support. All are strictly typed so you no need to use Mixed type anymore. The @sortBy is not only about standard sorting by columns but also allows use relations. 😎
Requirements
| Requirement | Constraint | Supported by |
|---|---|---|
| PHP | ^8.5 |
HEAD ⋯ 11.0.0 |
^8.4 |
HEAD ⋯ 8.0.0 |
|
^8.3 |
10.3.0 ⋯ 5.0.0 |
|
^8.2 |
7.2.0 ⋯ 2.0.0 |
|
^8.1 |
6.4.2 ⋯ 2.0.0 |
|
^8.0 |
4.6.0 ⋯ 2.0.0 |
|
^8.0.0 |
1.1.2 ⋯ 0.12.0 |
|
>=8.0.0 |
0.11.0 ⋯ 0.5.0 |
|
| Laravel | ^13.10.0 |
HEAD , 11.1.0 |
^13.0.0 |
11.0.0 |
|
^12.0.1 |
10.3.0 ⋯ 9.0.0 |
|
^11.0.8 |
8.1.1 ⋯ 8.0.0 |
|
^11.0.0 |
7.2.0 ⋯ 6.2.0 |
|
^10.34.0 |
7.2.0 ⋯ 6.2.0 |
|
^10.0.0 |
6.1.0 ⋯ 2.1.0 |
|
^9.21.0 |
5.6.0 ⋯ 5.0.0-beta.1 |
|
^9.0.0 |
5.0.0-beta.0 ⋯ 0.12.0 |
|
^8.22.1 |
3.0.0 ⋯ 0.5.0 |
|
| Lighthouse | ^6.66.0 |
HEAD ⋯ 11.0.0 |
^6.54.0 |
10.3.0 ⋯ 9.0.0 |
|
^6.36.0 |
8.1.1 ⋯ 8.0.0 |
|
^6.5.0 |
7.2.0 ⋯ 5.0.0-beta.0 |
|
^6.0.0 |
4.6.0 ⋯ 4.0.0 |
|
^5.68.0 |
3.0.0 ⋯ 2.0.0 |
|
^5.8.0 |
1.1.2 ⋯ 0.13.0 |
|
^5.6.1 |
0.12.0 , 0.11.0 |
|
^5.4 |
0.10.0 ⋯ 0.5.0 |
Installation
composer require lastdragon-ru/lara-asp-graphql
Configuration
Config can be used, for example, to customize supported operators for each type. Before this, you need to publish it via the following command, and then you can edit config/lara-asp-graphql.php.
php artisan vendor:publish --provider=LastDragon_ru\\LaraASP\\GraphQL\\PackageProvider --tag=config
Directives
@searchBy
Probably the most powerful directive to provide search (where conditions) for your GraphQL queries.
@sortBy
Probably the most powerful directive to provide sort (order by conditions) for your GraphQL queries.
@stream 🧪
Unlike the @paginate (and similar) directive, the @stream provides a uniform way to perform Offset/Limit and Cursor pagination of Eloquent/Query/Scout builders. Filtering and sorting enabled by default via @searchBy and @sortBy directives.
@type
Converts scalar into GraphQL Type. Similar to Lighthouse's @scalar directive, but uses Laravel Container to resolve instance and also supports PHP enums.
Scalars
Important
You should register the Scalar before use, it can be done via AstManipulator (useful while AST manipulation), TypeRegistry, or as a custom scalar inside the Schema:
scalar JsonString @type( class: "LastDragon_ru\\LaraASP\\GraphQL\\Scalars\\JsonStringType" )
JsonString
Represents JSON string.
Scout
Scout is also supported 🤩. You just need to add @search directive to an argument. Please note that available operators depend on Scout itself.
Please note that if the @search directive added, the generated query will expect the Scout builder only. So recommended using non-nullable String! type to avoid using the Eloquent builder (it will happen if the search argument missed or null; see also lighthouse#2465.
Input type auto-generation
The type used with the Builder directives like @searchBy/@sortBy may be Explicit (when you specify the input name field(where: InputTypeName @searchBy): [Object!]!) or Implicit (when the _ used, field(where: _ @searchBy): [Object!]!). They are processing a bit differently.
For Explicit type, all fields except unions and marked as ignored (if supported by the directive) will be included.
For Implicit type, the following rules are applied (in this order; concrete directive may have differences, please check its docs):
- Union? - exclude
- Has
Operatorof the concrete directive? - include - Has
Nuwave\Lighthouse\Support\Contracts\FieldResolver?- Yes
- Is
Nuwave\Lighthouse\Schema\Directives\RelationDirective? - Include if is theObjector list ofObject - Is
Nuwave\Lighthouse\Schema\Directives\RenameDirective? - Include if allowed, isscalar/enum(notObject), and no arguments - Otherwise - exclude
- Is
- No
- Is
Objector has arguments - exclude - Otherwise - include
- Is
- Yes
- Ignored (if supported)? - exclude
When converting the field, some of the original directives will be copied into the newly generated field. For the Explicit type, all directives except operators of other directives will be copied. For Implicit type, you can use Config::$allowedDirectives setting to control. Be aware of directive locations - the package doesn't perform any checks to ensure that the copied directive allowed on INPUT_FIELD_DEFINITION, it just copies it as is.
Builder field/column name
By default @searchBy/@sortBy will convert nested/related fields into dot string: eg {user: {name: asc}} will be converted into user.name. You can redefine this behavior by BuilderFieldResolver:
// AppProvider $this->app->bind( LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver::class, MyBuilderFieldResolver::class, );
Builder type detection
Directives like @searchBy/@sortBy have a unique set of operators and other features for each type of Builder (Eloquent/Scout/etc). Detection of the current Builder works fine for standard Lighthouse directives like @all, @paginated, @search, etc and relies on proper type hints of Relations/Queries/Resolvers. You may get BuilderUnknown error if the type hint is missed or the union type is used.
<?php declare(strict_types = 1); namespace App\Models; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Comment extends Model { protected $table = 'comments'; /** * Will NOT work */ public function user() { return $this->belongsTo(User::class); } /** * Must be */ public function user(): BelongsTo { return $this->belongsTo(User::class); } }
If you implement custom directives which internally enhance the Builder (like standard directives do), you may get BuilderUnknown error because the proper/expected builder type was not detected. In this case, your directive should implement BuilderInfoProvider interface and to specify the builder type explicitly.
<?php declare(strict_types = 1); namespace App\GraphQL\Directives; use Illuminate\Database\Eloquent\Builder; use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfo; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderInfoProvider; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use Nuwave\Lighthouse\Support\Contracts\Directive; use Override; class CustomDirective implements Directive, BuilderInfoProvider { #[Override] public static function definition(): string { return 'directive @custom'; } #[Override] public function getBuilderInfo(TypeSource $source): ?BuilderInfo { return BuilderInfo::create(Builder::class); } public function __invoke(): mixed { return null; } }
Printer
The package provides bindings for Printer so you can simply use:
<?php declare(strict_types = 1); use LastDragon_ru\GraphQL\Printer\Contracts\DirectiveFilter; use LastDragon_ru\GraphQL\Printer\Contracts\Printer; use LastDragon_ru\GraphQL\Printer\Settings\DefaultSettings; use LastDragon_ru\LaraASP\Dev\App\Example; use Nuwave\Lighthouse\Schema\SchemaBuilder; $schema = app()->make(SchemaBuilder::class)->schema(); $printer = app()->make(Printer::class); $settings = new DefaultSettings(); $printer->setSettings( $settings->setDirectiveDefinitionFilter( new class() implements DirectiveFilter { #[Override] public function isAllowedDirective(string $directive, bool $isStandard): bool { return !in_array($directive, ['eq', 'all', 'find'], true); } }, ), ); Example::raw($printer->print($schema), 'graphql');
Example output
The $printer->print($schema) is:
""" Use Input as Search Conditions for the current Builder. """ directive @searchBy on | ARGUMENT_DEFINITION directive @searchByOperatorAllOf on | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorAnyOf on | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorCondition on | INPUT_FIELD_DEFINITION directive @searchByOperatorContains on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorEndsWith on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorEqual on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorField on | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorIn on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorLike on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNot on | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotContains on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotEndsWith on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotEqual on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotIn on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotLike on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorNotStartsWith on | ENUM | INPUT_FIELD_DEFINITION | SCALAR directive @searchByOperatorStartsWith on | ENUM | INPUT_FIELD_DEFINITION | SCALAR """ Available conditions for `type User` (only one field allowed at a time). """ input SearchByConditionUser { """ Field condition. """ id: SearchByScalarID @searchByOperatorCondition """ Field condition. """ name: SearchByScalarString @searchByOperatorCondition } """ Available conditions for `type User` (only one field allowed at a time). """ input SearchByRootUser { """ All of the conditions must be true. """ allOf: [SearchByRootUser!] @searchByOperatorAllOf """ Any of the conditions must be true. """ anyOf: [SearchByRootUser!] @searchByOperatorAnyOf """ Field. """ field: SearchByConditionUser @searchByOperatorField """ Not. """ not: SearchByRootUser @searchByOperatorNot } """ Available operators for `scalar ID` (only one operator allowed at a time). """ input SearchByScalarID { """ Equal (`=`). """ equal: ID @searchByOperatorEqual """ Within a set of values. """ in: [ID!] @searchByOperatorIn """ Not Equal (`!=`). """ notEqual: ID @searchByOperatorNotEqual """ Outside a set of values. """ notIn: [ID!] @searchByOperatorNotIn } """ Available operators for `scalar String` (only one operator allowed at a time). """ input SearchByScalarString { """ Contains. """ contains: String @searchByOperatorContains """ Ends with a string. """ endsWith: String @searchByOperatorEndsWith """ Equal (`=`). """ equal: String @searchByOperatorEqual """ Within a set of values. """ in: [String!] @searchByOperatorIn """ Like. """ like: String @searchByOperatorLike """ Not contains. """ notContains: String @searchByOperatorNotContains """ Not ends with a string. """ notEndsWith: String @searchByOperatorNotEndsWith """ Not Equal (`!=`). """ notEqual: String @searchByOperatorNotEqual """ Outside a set of values. """ notIn: [String!] @searchByOperatorNotIn """ Not like. """ notLike: String @searchByOperatorNotLike """ Not starts with a string. """ notStartsWith: String @searchByOperatorNotStartsWith """ Starts with a string. """ startsWith: String @searchByOperatorStartsWith } type Query { """ Find a single user by an identifying attribute. """ user( """ Search by primary key. """ id: ID @eq ): User @find """ List multiple users. """ users( where: SearchByRootUser @searchBy ): [User!]! @all } """ Account of a person who utilizes this application. """ type User { """ Unique primary key. """ id: ID! """ Non-unique name. """ name: String! }
Testing Assertions
There are also a few useful assertions for PHPUnit to check printed/exported type/queries and more, please see the lastdragon-ru/lara-asp-graphql-testing package.
Upgrading
Please follow Upgrade Guide.
Contributing
Please use the main repository to report issues, send pull requests, or ask questions.
lastdragon-ru/lara-asp-graphql 适用场景与选型建议
lastdragon-ru/lara-asp-graphql 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 123.14k 次下载、GitHub Stars 达 5, 最近一次更新时间为 2021 年 03 月 22 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「stream」 「laravel」 「graphql」 「laravel-package」 「lighthouse」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 lastdragon-ru/lara-asp-graphql 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 lastdragon-ru/lara-asp-graphql 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 lastdragon-ru/lara-asp-graphql 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Object-Oriented API for PHP streams
Safely namespaced guzzle psr7 for WP2Static
Interface for a factory to create Psr\Http\Message\StreamInterface objects
Implementation of webignition/stream-factory-interface
High-performance PHP library for streaming JSON parsing with constant memory usage.
Alfabank REST API integration
统计信息
- 总下载量: 123.14k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 5
- 点击次数: 24
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-03-22