この記事では、GraphQL について説明し、PHP で GraphQL をインストールして使用する方法を詳しく紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
GraphQL は HTTP API インターフェイスを構築する最新の方法であり、クライアントは オンデマンド
必要なデータをクエリします。
GraphQL を使用すると、API 呼び出しの柔軟性が向上します。データベース クエリ ステートメントを記述するのと同じように、API に必要なデータを取得するようリクエストできます。これは、複雑な API クエリを構築する場合に非常に役立ちます。
REST の中心的な概念はリソースです。各リソースは URL で表すことができます。GET リクエストを通じて URL にアクセスして、このリソースを入手してください。現在のほとんどの API の定義によれば、JSON 形式でデータ応答を取得する可能性が高くなります。全体のプロセスは大まかに次のようになります:
GET /user/1 { "username":"姓名", "age":20, "sex":"男" }
GET /book/1 { "book":"书名", "author":"作者", "country":"中国" }
上の例からわかるように、フロントエンドで要求がある場合、 user /1
と book/1
は インターフェイスを
2 回呼び出す必要があり、フロントエンドが user/ の
username# のみを必要とする場合は、 1 ## の場合、上記のインターフェイスは
username 以外のデータを取得します。その場合、フロントエンドでは
username 以外のデータはどこにも存在せず、リソースが無駄になります。
GraphQL を使用してクエリを実行する場合、REST メソッドと比較して、
を 1 回呼び出すだけで済みます。 指定したフィールドをクエリできます。 、リソースの無駄を避け、より効率的になります。
query { user(id:1) { username } book(id:1){ book, author, country } }
composer require webonyx/graphql-php
<?php require_once __DIR__ . '/vendor/autoload.php'; use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\GraphQL; $queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'phoneNumber' => [ 'type' => Type::int(), 'resolve' => function () { return 1875555555; } ] ], ]); $schema = new Schema([ 'query' => $queryType, ]); $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $query = $input['query']; $variableValues = isset($input['variables']) ? $input['variables'] : null; try { $rootValue = ['prefix' => 'prefix: ']; $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); $output = $result->toArray(); } catch (\Exception $e) { $output = [ 'errors' => [ [ 'message' => $e->getMessage() ] ] ]; } header('Content-Type: application/json'); echo json_encode($output);
2. postman を使用して、先ほど作成したコードを呼び出します。以下はクエリ結果の例です
use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\GraphQL;
Option
query | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
必須。 データの読み取りに使用される、API のルートレベルのフィールドを含むオブジェクト タイプ (通常は「Query」という名前) を読み取ります。 | mutation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ルートレベルのフィールドを含むオブジェクト タイプを API に記述します (通常は「Mutation」という名前)。 |
| subscription# はデータが変更されるときに使用されます##ObjectType | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
は、将来の記述の実装のために予約されています。現在は | graphql-js です。 自己チェック クエリと互換性があり、さまざまなクライアント (Relay や GraphiQL など) に使用されます。
| #ディレクティブ Directive[] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
@skip | および@include が含まれます。 | カスタム ディレクティブを渡しても組み込みディレクティブを使用したい場合は、それらを明示的に追加します。例: array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]); ##types #ObjectType[] | オブジェクト型クラス テーブル。静的スキーマ解析中に |||||||||||||||||||||||||||||||||||||||||||||||||||||||
ほとんどの場合、オブジェクト型はフィールド内で直接参照されませんが、スキーマの一部である場合には引き続き使用されます。これは、オブジェクト型が | resolveType で呼び出しを実装して解決するためです。このオブジェクト タイプのインターフェイス。 | ここですべての型を渡す必要はないことに注意してください。これは、特定の使用例の単なる回避策です。 #typeLoader callable ##function($name) | 指定された型インスタンス名を返します。複数の呼び出しの場合は、同じインスタンスを返す必要があります。以下の遅延型ロードのセクションを参照してください。 |||||||||||||||||||||||||||||||||||||||||||||||||||||||
Option | Type | Notes |
---|---|---|
name | string | 必须。 Schema 中此对象的唯一名称 |
fields | array or callable | 必须。 描述对象字段或可调用返回此类数组的数组。 |
description | string | 呈现于客户端的参数文本说明(例如:用于 GraphiQL 自动生成文档 ) |
interfaces | array or callable | 此类型实现的接口列表或返回此类列表的可调用接口。 |
<?php use GraphQL\Type\Definition\Type; // 内置标量类型 Type::string(); // String 类型 Type::int(); // Int 类型 Type::float(); // Float 类型 Type::boolean(); // Boolean 类型 Type::id(); // ID 类型
GraphQL 对象类型上的所有字段都有 0 个或多个参数,使用在 args 的字段定义上。每个参数数组参考以下说明:
Option | Type | Notes |
---|---|---|
name | string | 必须。 参数名称。 为空时,使用 args 数组键值 |
type | Type | 必须。 |
description | string | 呈现于客户端的参数文本说明 |
defaultValue | scalar | 当前参数默认值 |
示例
$queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'phoneNumber' => [ 'type' => Type::int(), 'resolve' => function () { return 1875555555; } ] ], ]);
GraphQL类主要在查询的时候用到,我们可以用 GraphQL::executeQuery 方法来执行查询
executeQuery 方法的参数说明
参数 | 类型 | 说明 |
---|---|---|
schema | GraphQL\Type\Schema | 必须。 Schema应用实例 |
queryString | string or GraphQL\Language\AST\DocumentNode | 必须。 解析,验证并执行现有的 GraphQL 查询字符。 如果在执行之前解析其他查询,则在此处传递相应的 AST 文档节点来避免新的解析。 |
rootValue | mixed | 表示数据图结构的基础值。作为Query type 字段解析传递的第一个参数。如果现有该值已被 Query type 解析过,则可忽略或设置为 null 值。 |
context | mixed | 字段解析器的共享信息。 常用来传递已登录用户信息,位置详情等。 它将用在所有字段解析器的第 3 个参数。 |
variableValues | array | 变量的映射,该值将随同查询字符串一起传递。请查阅 GraphQL官网查询变量的相关。 |
operationName | string | 指定请求方可执行的操作, 防止条件查询字符包含多级操作。 |
fieldResolver | callable | Schema 参数 schema 中未实现的解析器函数。 |
validationRules | array | 查询验证规则组,默认所有规则。空数组将跳过查询验证 (对于持久化查询将会比较方便,查询会在持久化之前默认已验证,并在执行期间假设符合规则)。 |
use GraphQL\GraphQL; $result = GraphQL::executeQuery( $schema, $queryString, $rootValue = null, $context = null, $variableValues = null, $operationName = null, $fieldResolver = null, $validationRules = null );
我们介绍完GraphQL几个概念之后,用几个简单的示例带大家来体验一下。
在这个示例中我们定义了2个字段,分别是phoneNumber
和echo
,其中phoneNumber为 Type::int()
类型,echo
为Type::string()
类型,同时echo
字段带有一个参数为message
<?php require_once __DIR__ . '/vendor/autoload.php'; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\GraphQL; use GraphQL\Type\Schema; $queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'phoneNumber' => [ 'type' => Type::int(), 'resolve' => function () { return 1875555555; } ], 'echo' => [ 'type' => Type::string(), 'args' => [ 'message' => Type::string(), ], 'resolve' => function ($root, $args) { return 'echo msg result:' . ($args['message'] ?? 'nothing'); } ], ], ]); $schema = new Schema([ 'query' => $queryType ]); $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $query = $input['query']; $variableValues = isset($input['variables']) ? $input['variables'] : null; try { $rootValue = ['prefix' => 'prefix: ']; $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); $output = $result->toArray(); } catch (\Exception $e) { $output = [ 'errors' => [ [ 'message' => $e->getMessage() ] ] ]; } header('Content-Type: application/json'); echo json_encode($output);
我们可以看到,在请求时我们传了phoneNumber
和echo
两个字段,并且message
为test
。
我们在上面说过,对象类型是典型的 GraphQL 应用程序中使用最频繁的基元,一个对象类型里面可以包含宁外一个对象类型,我们可以新定义一个名为$userType
的ObjectType
,然后在oneUser
指定它的类型为$userType
,这样我们执行查询的时候,oneUser
就会返回一个对象。
<?php require_once __DIR__ . '/vendor/autoload.php'; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\GraphQL; use GraphQL\Type\Schema; $userType = new ObjectType([ 'name' => 'userType', 'description' => '用户详情', 'fields' => [ 'uid' => [ 'type' => Type::int(), 'description' => '用户ID' ], 'name' => Type::string() ] ]); $queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'oneUser' => [ 'type' => $userType, // 我们这里指定type为我们上面创建的$userType 'description' => '用户列表', 'args' => [ 'uid' => [ 'type' => Type::int(), 'defaultValue' => 222 ] ], 'resolve' => function($root, $args) { return [ "uid" => $args['user_id'] ?? 3, "name" => "xzl", ]; } ], ] ]); $schema = new Schema([ 'query' => $queryType ]); $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $query = $input['query']; $variableValues = isset($input['variables']) ? $input['variables'] : null; try { $rootValue = ['prefix' => 'prefix: ']; $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); $output = $result->toArray(); } catch (\Exception $e) { $output = [ 'errors' => [ [ 'message' => $e->getMessage() ] ] ]; } header('Content-Type: application/json'); echo json_encode($output);
在平时的开发请求中,我们从后端接口获取数据的时候,大部分都是以列表的形式返回的,我们可以通过Type::listOf
方法来指定我们返回的字段是一个列表。
<?php require_once __DIR__ . '/vendor/autoload.php'; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\GraphQL; use GraphQL\Type\Schema; class User { // 模拟从数据库取数据 public static function getUserLimit($limit) { $user = [ [ "uid" => 1, "name" => "name1" ], [ "uid" => 2, "name" => "name2" ], [ "uid" => 3, "name" => "name3" ], [ "uid" => 4, "name" => "name4" ] ]; return array_slice($user, 0, $limit); } } $userType = new ObjectType([ 'name' => 'userType', 'description' => '用户详情', 'fields' => [ 'uid' => [ 'type' => Type::int(), 'description' => '用户ID' ], 'name' => Type::string() ] ]); $queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'users' => [ 'type' => Type::listOf($userType), 'description' => '用户列表', 'args' => [ 'limit' => [ 'type' => Type::int(), 'description' => '限制条数', 'defaultValue' => 10 ] ], 'resolve' => function($root, $args) { return User::getUserLimit($args['limit']); } ] ] ]); $schema = new Schema([ 'query' => $queryType ]); $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $query = $input['query']; $variableValues = isset($input['variables']) ? $input['variables'] : null; try { $rootValue = ['prefix' => 'prefix: ']; $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); $output = $result->toArray(); } catch (\Exception $e) { $output = [ 'errors' => [ [ 'message' => $e->getMessage() ] ] ]; } header('Content-Type: application/json'); echo json_encode($output);
从上面结果可以看到,我们传了limit
参数为2,最终从我们模拟的数据里面取出了2条数据
在上面的示例中,如果我们代码返回的数据比较复杂时,需要编写大量的代码,通过GraphQL类型语言,我们可以减少代码量,使代码看上去更加简洁,这是一个用 GraphQL 类型语言定义的简单 Schema示例。
<?php require_once __DIR__ . '/vendor/autoload.php'; use GraphQL\GraphQL; use GraphQL\Utils\BuildSchema; // graph.graphql 文件内容 $graph = <<<GRAPH schema { query: Query } type Query { graph_test: String echo(message: String): String show_test: Show show_test_arr: [Show] } type Show { content: String! text: String! } GRAPH; $schema = BuildSchema::build($graph); $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $query = $input['query']; $variableValues = isset($input['variables']) ? $input['variables'] : null; try { $rootValue = [ 'sum' => function($rootValue, $args, $context) { return $args['x'] + $args['y']; }, 'echo' => function($rootValue, $args, $context) { return $rootValue['prefix'] . ($args['message'] ?? 'no echo'); }, 'show_test' => function($rootValue, $args, $context) { return [ 'content' => 'show_content', 'text' => 'xxxx xxx' ]; }, 'show_test_arr' => function($rootValue, $args, $context) { return [ [ 'content' => 'show_content', 'text' => 'xxxx xxx' ], [ 'content' => 'show_content_2', 'text' => 'xxxx xxx_2' ] ]; }, 'prefix' => 'from test:', "graph_test" => "graphql_test" ];; $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); $output = $result->toArray(); } catch (\Exception $e) { \GraphQL\Server\StandardServer::send500Error($e); } header('Content-Type: application/json'); echo json_encode($output);
更多编程相关知识,请访问:编程视频!!
以上がPHPにGraphQLをインストールして使う方法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。