[淺談]在 Laravel 中使用 GraphQL(二)

Jian-Kai,Kuo
LT Lab
Published in
11 min readNov 25, 2019
圖片來自: https://blog.pusher.com/graphql-laravel/

前言

在上一篇淺談中,我們談到了透過 Xampp 架設 Laravel 框架,並且連接 MySQL 中的資料庫,最後透過指令將我們設定的 migraions 在資料庫中產生相對應的資料表。

Laravel → factory + seeder → 資料庫新增資料

Laravel 提供了可以自動產生資料的方法,透過在 factories 裡設定好要如何產生資料,就能夠在資料庫中自動的產出資料了。

我們打開 factories 中任意一個檔案會看到裡面空空如也,因為我們需要自己去撰寫資料表中每一筆資料是要如何去產生的。

$factory->define([資料表model]::class, function (Faker $faker) {    return [        "name" => $faker->name, // Faker 中 隨機的 名稱        "product_type_id" => mt_rand(1, 5), // 1~5隨機數字        "description" => Str::random(4), // 隨機長度為4的字串        "price" => mt_rand(10, 100),    ];});

所以我們需要針對上次建立好的四個資料表的欄位進行各個欄位的資料填寫,由於資料需要一點隨機性,所以利用 Faker 這個套件來隨機產生資料內容。

Faker 這個套件有許多已經寫好的資料內容可以去取用,詳細資料可以觀看 github 上的文件。

四個 model 的 factory 用來產生資料

有了 factory 後我們需要有驅動工場的動力, seeder 就是可以驅動工廠的動能。首先,我們透過指令 php artisan make::seeder ProductSeeder ,會在 database/seeds 資料夾下新增 ProductSeeder.php

$ php artisan make:seeder [Seeder Name]

我們需要在 seeder 裡面設定每一個資料表需要產生的筆數或是要在資料庫中直接新增那些資料。

我們需要去 app 資料夾引用相關的 model,然後在 run 函式中設定要產生進去資料庫的資料筆數。

可以透過下面的指令產生資料:

$ php artisan db:seed --class[seeder 的 class Name]

執行完上面的指令後,到 MySQL 資料庫就可以看到四個資料表都填入設定好的資料筆數了。

資料表 products 中新增了 50 筆資料

我們在 database/seeds/DatabaseSeeder.php 的 run function 中添加程式碼 $this->call(ProductSeeder::class); 指定到對應的 seeder ,就可以透過下面的指令,將現有的資料庫從新刷新,產生新的資料表跟資料。

$ php artisan migrate:refresh --seed

GraphQL:安裝

文章到了這邊終於進入了我們的主題「GraphQL」,到目前為止我們已經透過了 Laravel 成功地在資料庫中產生了幾筆資料,我們就可以透過 GraphQL 進行資料的撈取了。

首先,我們需要先安裝 GraphQL 的套件以及相關設定:

$ composer require rebing/graphql-laravel

接者到 config\app.php ,在 providers 和 aliases 中加入:

// providers
Rebing\GraphQL\GraphQLServiceProvider::class
//aliases
'GraphQL' => Rebing\GraphQL\Support\Facades\GraphQL::class

接者執行 下面指令來產生 GraphQL 相關的 config 檔:

$ php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"

最後會產生 config\graphql.php 並且看到相關的設定。

GraphQL:Schemas

GraphQL相較於REST以及其他web service架構提供了一種高效、強大和靈活的開發web APIs的方式。它通過由客戶端根據所需定義資料結構,同時由服務端負責返回相同資料結構的對應數據的方式避免了服務端大量冗餘數據的返回,但與此同時也意味著這種方式不能有效利用起查詢結果的web緩存。GraphQL這種查詢語言所帶來的靈活性和豐富性的同時也增加了複雜性,使得這項技術對於簡單APIs並不是好的選擇。
— 引用至 https://zh.wikipedia.org/wiki/GraphQL

GraphQl 是透過一串 query 指令像資料庫請求需要的相關資料,像是:

query {
users(id:5){
id
name
job
}
}

上面的指令結構告訴了 GraphQL 我們要去 users 資料表中找到 id 為 5 的哪個 user 的 id 、 name 、 以及 job。

首先,我們先在 app 資料夾中新增 GraphQL 資料夾,我們會將相關的檔案放置在這個資料夾中。

接者在 app\GraphQL 中新增三個資料夾,分別為 Mutation Query 以及 Type ,三個資料夾中放置的檔案有不同的功用。

  1. Mutation 資料夾:負責資料的更新或是資料新增。
  2. Query 資料夾:負責定義查詢時的參數以及處理。
  3. Type 資料夾:負責 Query 時回傳的資料格式。

資料夾建完資後,我們先到 app\Type 中新增 ProductType.php ProductCategoryType.php 以及 ProductTagType.php 三個檔案。

Type 資料夾
ProductType.php 、 ProductCategoryType.php 以及 ProductTagType.php

定義完 Type 後,我們需要定義 Query 來讓 GraphQL 接收我們的 Query 字串。這次的淺談我們只針對商品進行資料的請求,因此我們只在 Query 資料夾中新增 ProductQuery.php ,來獲得商品的資料。若需要得到其他資料表的資料,可以參考 ProductQuery.php 是如何設置的。

ProductQuery.php

其中, type 函式會從 config\graphql.php 的 type 中找到 product 的資料格式以及型別。resolve 函式則是會簡單的判斷 query 的參數有 id 會去找出此 id 的商品,沒有則是回傳整個 products 資料表的商品資料。

接者要在 config\graphql.php 設定 query 時的 schemas 跟 資料回傳時的 types。

config\graphql.php 引用相關 class
在 schemas 中設定 product 的 query
在 types中設定相關的 type

完成上述的動作後,我們就完成了基礎的 GraphQL 的設定了,接者我們需要在安裝測試工具來測試我們的 GraphQL 能不能作用了。

GraphQL:安裝測試工具及測試

這裡我們使用 mll-lab/laravel-graphql-playground 來測試我們設定好的 GraphQL 能不能作用。

$ composer require mll-lab/laravel-graphql-playground

config\app.php 中加入 provider

'providers' => [
// Other providers...
MLL\GraphQLPlayground\GraphQLPlaygroundServiceProvider::class,
]

接者執行下面指令,產生 config/graphql-playground.php

php artisan vendor:publish --provider="MLL\GraphQLPlayground\GraphQLPlaygroundServiceProvider" --tag=config

最後在瀏覽器打開 http://graphql.local/graphql-playground 就可以看到 GraphQL 的測試環境了。

GraphQL 測試環境

測試看看可不可以從資料庫拿到資料。

成功拿到全部 product 資料
成功拿到 id 為 5 的 product 資料

這次的淺談,我們談到如何使用 factory 加上 seed 來產生資料集,接著透過 GraphQL 在資料庫裡面請求資料。而我們在這次也終於有提到了 GraphQL 的相關設定以及程式碼的演示,當我們將 Query 的 schema 結構定義清楚以及 resolve 該做出甚麼動作,我們就可以透過 GraphQL 來向資料庫請求資料了。

下一次的淺談,我們會談到如何處理資料表之間的關聯,以及如果要新增或式修改資料時該如何去處理。

謝謝各位的觀看,如有任何問題或是有寫錯的部分也可以在下方留言。

相關參考資料:

graphql-laravel:

laravel-graphql-playground:

在 Laravel 中使用 GraphQL 一【获取数据】:

多面體工作室 Dometi — Laravel

Laravel 官方文件

備註:

如果有遇到 Laravel 無法解析 class 的問題,可以參考下面連結的解決方法。

--

--