什麼是GraphQL?
GraphQL 是一種 API 查詢語言,GraphQL 對你的 API 中的資料提供了一套易於理解的完整描述,使得客戶端能夠準確地獲得它需要的資料,而且沒有任何冗餘,也讓 API 更容易地隨著時間推移而演進,還能用於構建強大的開發者工具。
簡單來說,GraphQL 不同於REST API,REST API 請求多個資源時得載入多個 URL,而 GraphQL 可以通過一次請求就獲取你應用所需的所有資料。這樣一來,即使是比較慢的行動網路連線下,使用 GraphQL 的應用也能表現得足夠迅速。查詢方式類似下面這樣子:
{
user {
id
name
job {
name
description
}
}
}
// 查詢得到的資料格式是:
{
"data": {
"users": [
{
"id": 1,
"name": "kwen",
"job": [
{
"name": "前端開發工程師",
"description": "前端前端"
}
]
},
{
"id": 2,
"name": "kwen1",
"job": [
{
"name": "PHP開發工程師",
"description": "PHP"
}
]
}
]
}
}
你可以在 這裡 檢視更多關於 GraphQL 的資訊
在 Laravel 中使用 GraphQL
以下我會用一個簡單的demo來演示如何使用
1、安裝 Laravel
$ composer global require "laravel/installer"
$ laravel new laravel-graphql-test
$ cd laravel-graphql-test
我這裡使用的是valet 作為開發環境,詳細的安裝也可以到文件中檢視
2、安裝 graphql-laravel package
修改composer.json
$ composer require rebing/graphql-laravel
新增 service provider (laravel5.5 + 會自動註冊)
// 新增到app/config/app.php
Rebing\GraphQL\GraphQLServiceProvider::class,
// 新增alias
'GraphQL' => 'Rebing\GraphQL\Support\Facades\GraphQL',
生成配置檔案
$ php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"
然後就可以到 config/graphql.php
檢視配置資訊了
3、建立資料模型
生成模型和資料庫表遷移檔案
$ php artisan make:model Job -m
Model created successfully.
Created Migration: 2018_02_14_152840_create_jobs_table
建立模型關係
// app/Models/User.php
...
class User extends Authenticatable
{
...
public function job()
{
return $this->hasMany('App\Models\Job');
}
}
// app/Models/Job.php
...
class Job extends Model
{
public function user()
{
return $this->belongsTo("App\Models\User");
}
}
修改migration
// xxx_create_jobs_table.php
...
class CreateJobsTable extends Migration
{
public function up()
{
Schema::create('jobs', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->string('name');
$table->text('description')->nullable();
$table->timestamps();
});
}
...
}
遷移 migration
$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrating: 2018_02_14_152840_create_jobs_table
Migrated: 2018_02_14_152840_create_jobs_table
4、建立 GraphQL 的 Query 和 Type
GraphQL 是一個基於型別系統來執行查詢的,所以需要定義好暴露的查詢介面 (Query) 以及 介面的型別 (Type)
Type 會幫助我們格式化查詢結果的型別,一般為boolean、string、float、int等,另外還可以定義自定義型別
目錄結構
圖為GraphQL目錄結構
定義Type
// app/GraphQL/Type/UsersType.php
<?php
namespace App\GraphQL\Type;
use App\Models\User;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
class UsersType extends GraphQLType
{
protected $attributes = [
'name' => 'Users',
'description' => '使用者',
'model' => User::class
];
/**
* 定義返回的欄位介面
* @return array
*/
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => '使用者id'
],
'name' => [
'type' => Type::string(),
'description' => '使用者名稱'
],
'email' => [
'type' => Type::string(),
'description' => '使用者的email'
],
'job' => [
'type' => Type::listOf(GraphQL::type('jobs')),
'description' => '使用者的工作欄位'
]
];
}
}
// app/GraphQL/Type/JobsType.php
<?php
namespace App\GraphQL\Type;
use App\Models\Job;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
class JobsType extends GraphQLType
{
protected $attributes = [
'name' => 'jobs',
'description' => '工作',
'model' => Job::class
];
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => '工作id'
],
'name' => [
'type' => Type::string(),
'description' => '工作名'
],
'description' => [
'type' => Type::string(),
'description' => '工作職責描述'
]
];
}
}
定義查詢介面 Query
// app/GraphQL/Query/UsersQuery.php
<?php
namespace App\GraphQL\Query;
use GraphQL;
use App\Models\User;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
class UsersQuery extends Query
{
protected $attributes = [
'name' => 'users'
];
public function type()
{
return Type::listOf(GraphQL::type('users'));
}
/**
* 接收引數的型別定義
* @return array
*/
public function args()
{
return [
'id' => ['name' => 'id', 'type' => Type::int()],
'email' => ['name' => 'email', 'type' => Type::string()],
'limit' => ['name' => 'limit', 'type' => Type::int()],
];
}
/**
* @param $root
* @param $args 傳入引數
*
* 處理請求的邏輯
* @return mixed
*/
public function resolve($root, $args)
{
$user = new User;
if(isset($args['limit']) ) {
$user = $user->limit($args['limit']);
}
if(isset($args['id']))
{
$user = $user->where('id' , $args['id']);
}
if(isset($args['email']))
{
$user = $user->where('email', $args['email']);
}
return $user->get();
}
}
// app/GraphQL/Query/JobsQuery.php
<?php
namespace App\GraphQL\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
class JobsQuery extends Query
{
protected $attributes = [
'name' => 'jobs'
];
public function type()
{
return Type::listOf(GraphQL::type('jobs'));
}
public function args()
{
return [
'id' => ['name' => 'id', 'type' => Type::int()],
'name' => ['name' => 'name', 'type' => Type::string()],
];
}
}
5、測試結果
接下來就可以開始測試了
填充測試資料
因為資料庫裡面什麼資料都沒有,所以首先需要填充測試資料,這裡使用的是 seed 進行填充
// database/seeds/UsersTableSeeder.php
...
class UsersTableSeeder extends Seeder
{
public function run()
{
DB::table('users')->insert([
'name' => 'kwen',
'email' => 'email@email.com',
'password' => bcrypt('123456'),
]);
DB::table('users')->insert([
'name' => 'kwen1',
'email' => 'email1@email.com',
'password' => bcrypt('123456'),
]);
}
}
// database/seeds/JobsTableSeeder.php
...
class JobsTableSeeder extends Seeder
{
public function run()
{
DB::table('jobs')->insert([
'user_id' => 1,
'name' => '前端開發工程師',
'description' => '前端前端'
]);
DB::table('jobs')->insert([
'user_id' => 2,
'name' => 'PHP開發工程師',
'description' => 'PHP'
]);
}
}
// database/seeds/DatabaseSeeder.php
...
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(JobsTableSeeder::class);
}
}
修改完這兩個檔案之後使用 artisan 命令進行填充
$ php artisan db:seed
Seeding: UsersTableSeeder
Seeding: JobsTableSeeder
安裝測試工具
這裡使用的是 GraphQL 視覺化除錯工具,專門針對 Laravel 的 noh4ck/laravel-graphiql
1、安裝 laravel-graphiql
$ composer require "noh4ck/graphiql:@dev"
2、開啟 config/app.php
並新增以下程式碼到 providers
中
Graphiql\GraphiqlServiceProvider::class
3、釋出這個包並生成 config/graphiql.php
配置檔案
$ php artisan graphiql:publish
測試資料
執行 php artisan serve
然後開啟http://127.0.0.1:8000/graphql-ui 就可以開啟測試工具的介面了
如果要查詢某個特定 id 或者特定引數的 user ,則可以帶引數進行查詢
限定 2 個使用者
所傳引數的設定可以在app/GraphQL/Query/UsersType.php
中設定,resolve
方法裡面就是設定引數邏輯的
總結
這篇文章簡單地介紹瞭如何在 Laravel 中使用 GraphQL 作為 API 查詢語言了,使用的是 noh4ck/laravel-graphiql ,但是使用中覺得這個包的還不夠完美,如果在生成 Type 或者 Query的時候能用 artisan 命令就好了,我已經在github 上面提了 issue 並得到相關回復,應該很快就可以使用這些功能了。
有人說傳統Restful API已死,GraphQL永生,GraphQL解決的就是Restful 的缺點,但同時GraphQL也存在很多效能的問題,GraphQL 真正要完全替代 Restful API 還有很長一段路要走,讓我們拭目以待吧!
往後文章中還會繼續介紹這個包的更多用法,例如如何修改資料、增加資料、刪除資料還有授權認證authenticated等等,第一次寫文章,希望能多多支援。
本文 demo 可以到 github 上檢視
下一節: 在 Laravel 中使用 GraphQL 二【修改資料】
參考
本作品採用《CC 協議》,轉載必須註明作者和本文連結