Membangun Server GraphQL dengan Laravel

Diterbitkan: 2022-03-11

Jika Anda masih belum terbiasa dengannya, GraphQL adalah bahasa kueri yang digunakan untuk berinteraksi dengan API Anda yang memberikan beberapa manfaat dibandingkan dengan arsitektur alternatif seperti REST. GraphQL sangat berguna saat digunakan sebagai titik akhir untuk aplikasi seluler dan satu halaman. GraphQL memungkinkan Anda untuk menanyakan data bersarang dan terkait dalam permintaan dengan relatif mudah, memungkinkan pengembang untuk mendapatkan data yang tepat yang mereka butuhkan dalam satu perjalanan pulang pergi ke server.

Laravel adalah kerangka kerja web PHP yang populer dan berpendirian. Ini menyediakan banyak alat bawaan untuk menjalankan dan menjalankan aplikasi dengan cepat, tetapi juga memungkinkan pengembang untuk menukar implementasi mereka sendiri untuk antarmuka bawaan Laravel bila diinginkan.

Meskipun komunitas di sekitar GraphQL dan Laravel telah tumbuh secara dramatis sejak mereka bersumber terbuka, dokumentasi yang menjelaskan cara menggunakan kedua teknologi ini bersama-sama masih agak langka.

Jadi, dalam tutorial ini, saya akan menunjukkan cara membuat server GraphQL Anda sendiri menggunakan Laravel.

Ulasan Proyek

Ilustrasi gambaran umum server GraphQL

Sebelum kita mulai, kita harus membiasakan diri dengan proyek yang sedang kita coba bangun. Untuk melakukan itu, kami akan mendefinisikan sumber daya kami dan membuat skema GraphQL kami, yang nantinya akan kami gunakan untuk melayani API kami.

Sumber Daya Proyek

Aplikasi kami akan terdiri dari dua sumber: Artikel dan Pengguna . Sumber daya ini akan didefinisikan sebagai tipe objek dalam skema GraphQL kami:

 type User { id: ID! name: String! email: String! articles: [Article!]! } type Article { id: ID! title: String! content: String! author: User! }

Melihat skema, kita dapat melihat bahwa kita memiliki hubungan satu-ke-banyak antara dua objek kita. Pengguna dapat menulis banyak artikel, dan sebuah artikel memiliki penulis (pengguna) yang ditugaskan padanya.

Sekarang setelah kita mendefinisikan tipe objek, kita memerlukan cara untuk membuat dan mengkueri data kita, jadi mari kita definisikan objek kueri dan mutasi kita:

 type Query { user(id: ID!): User users: [User!]! article(id: ID!): Article articles: [Article!]! } type Mutation { createUser(name: String!, email: String!, password: String!): User createArticle(title: String!, content: String!): Article }

Menyiapkan Proyek Laravel Kami

Sekarang setelah kita mendefinisikan skema GraphQL kita, mari kita jalankan dan jalankan proyek Laravel kita. Mari kita mulai dengan membuat proyek Laravel melalui Composer baru:

 $ composer create-project --prefer-dist laravel/laravel laravel-graphql

Hanya untuk memastikan semuanya berfungsi, mari kita boot server kita dan pastikan kita melihat halaman default Laravel:

 $ cd laravel-graphql $ php artisan serve Laravel development server started: <http://127.0.0.1:8000>

Model Basis Data dan Migrasi

Untuk keperluan artikel ini, kita akan menggunakan SQLite. Jadi, mari buat perubahan berikut pada file .env default:

 DB_CONNECTION=sqlite # DB_HOST= # DB_PORT= # DB_DATABASE=database.sqlite # DB_USERNAME= # DB_PASSWORD=

Selanjutnya, mari kita buat file database kita:

 $ touch ./database/database.sqlite

Laravel dikirimkan dengan model pengguna dan beberapa file migrasi dasar. Mari dengan cepat menambahkan kolom api_token ke dalam file migrasi CreateUsersTable kami yang disediakan oleh Laravel:

 /database/migrations/XXXX_XX_XX_000000_create_users_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. */ public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('api_token', 80)->unique()->nullable()->default(null); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down() { Schema::dropIfExists('users'); } }

Kami akan melingkari kembali kolom tambahan ini nanti di artikel saat kami mendapatkan otorisasi. Sekarang mari kita lanjutkan dan buat model artikel kita dan file migrasi untuk membuat tabel terkait:

 $ php artisan make:model Article -m

Catatan: Opsi -m membuat file migrasi untuk model artikel kami yang baru dibuat.

Mari buat beberapa penyesuaian pada file migrasi yang dihasilkan:

 use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticlesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('user_id'); $table->string('title'); $table->text('content'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }

Kami telah menambahkan kunci asing yang menunjuk ke id pada tabel users kami serta kolom title dan content yang kami definisikan dalam skema GraphQL kami.

Sekarang setelah file migrasi kita ditentukan, mari kita lanjutkan dan menjalankannya terhadap database kita:

 $ php artisan migrate

Selanjutnya, mari perbarui model kita dengan mendefinisikan hubungan yang diperlukan:

 app/User.php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; // ... /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function articles() { return $this->hasMany(Article::class); } }
 app/Article.php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'title', 'content', ]; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class); } }

Pembibitan Basis Data

Sekarang setelah kita menyiapkan model dan migrasi, mari kita seed database kita. Kami akan mulai dengan membuat beberapa kelas seeder untuk articles dan tabel users kami:

 $ php artisan make:seeder UsersTableSeeder $ php artisan make:seeder ArticlesTableSeeder

Selanjutnya, mari kita atur untuk memasukkan beberapa data dummy ke dalam database SQLite kita:

 database/seeds/UsersTableSeeder.php use App\User; use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\User::truncate(); $faker = \Faker\Factory::create(); $password = bcrypt('secret'); \App\User::create([ 'name' => $faker->name, 'email' => '[email protected]', 'password' => $password, ]); for ($i = 0; $i < 10; ++$i) { \App\User::create([ 'name' => $faker->name, 'email' => $faker->email, 'password' => $password, ]); } } }
 database/seeds/ArticlesTableSeeder.php use App\Article; use Illuminate\Database\Seeder; class ArticlesTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\Article::truncate(); \App\Article::unguard(); $faker = \Faker\Factory::create(); \App\User::all()->each(function ($user) use ($faker) { foreach (range(1, 5) as $i) { \App\Article::create([ 'user_id' => $user->id, 'title' => $faker->sentence, 'content' => $faker->paragraphs(3, true), ]); } }); } }
 /database/seeds/DatabaseSeeder.php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); $this->call(ArticlesTableSeeder::class); } }

Terakhir, mari kita jalankan seeder database kita untuk mendapatkan beberapa data ke dalam database kita:

 $ php artisan db:seed

Mercusuar Laravel dan Server GraphQL

Sekarang kita telah menyiapkan database dan model kita, saatnya untuk mulai membangun server GraphQL kita. Saat ini, ada beberapa solusi yang tersedia untuk Laravel, tetapi untuk artikel ini, kita akan menggunakan Lighthouse.

Lighthouse adalah paket yang saya buat beberapa tahun yang lalu dan baru-baru ini melihat beberapa dukungan luar biasa dari komunitas yang berkembang di sekitarnya. Ini memungkinkan pengembang untuk dengan cepat mengatur server GraphQL menggunakan Laravel dengan sedikit boilerplate sementara juga cukup fleksibel untuk memungkinkan pengembang menyesuaikannya agar sesuai dengan kebutuhan hampir semua proyek.

Ilustrasi Laravel Lighthouse dan GraphQL Server

Mari kita mulai dengan menarik paket ke dalam proyek kita:

 $ composer require nuwave/lighthouse:"3.1.*"

Selanjutnya, mari kita publikasikan file konfigurasi Lighthouse:

 $ php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider" --tag=config

Catatan: Anda juga dapat memilih untuk memublikasikan file skema default Lighthouse hanya dengan menghapus opsi --tag=config . Tetapi untuk tujuan artikel ini, kita akan membuat file skema kita dari awal.

Jika kita melihat file config/lighthouse.php Anda akan melihat pengaturan yang digunakan untuk mendaftarkan file skema kita dengan Lighthouse:

 'schema' => [ 'register' => base_path('graphql/schema.graphql'), ],

Jadi mari kita lanjutkan dan buat file skema kita dan atur jenis objek dan kueri pengguna kita:

 $ mkdir graphql $ touch ./graphql/schema.graphql /graphql/schema.graphql type User { id: ID! name: String! email: String! } type Query { user(id: ID! @eq): User @find users: [User!]! @all }

Anda akan melihat bahwa skema kami terlihat mirip dengan yang kami definisikan sebelumnya kecuali kami telah menambahkan beberapa pengidentifikasi yang disebut arahan skema.

Mari luangkan waktu sejenak untuk memecah skema yang kita definisikan. Definisi pertama kami adalah tipe objek yang disebut User yang memiliki hubungan dengan model fasih App\User kami. Kami mendefinisikan id , name dan email sebagai bidang yang dapat ditanyakan dari model User kami. Atau, ini berarti kolom password , created_at dan updated_at adalah bidang yang tidak dapat ditanyakan dari API kami.

Selanjutnya kita memiliki tipe Query yang merupakan titik masuk ke API kita dan dapat digunakan untuk query data. Bidang pertama kami adalah bidang users yang mengembalikan array tipe objek User . Arahan @all memberi tahu Lighthouse untuk menjalankan kueri Eloquent, menggunakan model User kami dan mendapatkan semua hasilnya. Ini akan sama dengan menjalankan yang berikut:

 $users = \App\User::all();

Catatan: Lighthouse tahu untuk mencari model di ruang nama \App\User karena opsi namespaces yang ditentukan dalam file konfigurasinya.

Bidang yang ditentukan kedua kami pada jenis kueri kami adalah panggilan user , yang mengambil id sebagai argumen dan mengembalikan satu jenis objek User . Kami juga telah menambahkan dua arahan untuk membantu Lighthouse secara otomatis membuat kueri untuk kami dan mengembalikan satu model User . Arahan @eq memberitahu Lighthouse untuk menambahkan tempat pada kolom id kita, dan arahan @find menginstruksikan Lighthouse untuk mengembalikan satu hasil. Untuk menulis kueri ini menggunakan pembuat kueri Laravel, akan terlihat seperti ini:

 $user = \App\User::where('id', $args['id'])->first();

Menanyakan GraphQL API Kami

Sekarang kita memiliki sedikit wawasan tentang bagaimana Lighthouse menggunakan skema kita untuk membuat kueri, mari jalankan server kita dan mulai kueri data. Kami akan mulai dengan menjalankan server kami:

 $ php artisan serve Laravel development server started: <http://127.0.0.1:8000>

Untuk menanyakan titik akhir GraphQL, Anda dapat menjalankan perintah cURL di terminal atau klien standar seperti Postman. Namun, untuk mendapatkan manfaat penuh dari GraphQL (seperti pelengkapan otomatis, penyorotan kesalahan, dokumentasi, dll., kami akan menggunakan GraphQL Playground (rilis unduhan di sini).

Saat memulai Playground, klik pada tab “URL Endpoint”, dan ketikkan http://localhost:8000/graphql untuk mengarahkan GraphQL Playground ke server kami. Di sisi kiri editor, kita dapat melakukan kueri untuk data kita, jadi mari kita mulai dengan menanyakan semua pengguna yang kita gunakan untuk seed database:

 { users { id email name } }

Saat Anda menekan tombol putar di tengah IDE (atau klik Ctrl+Enter ), Anda akan melihat output JSON dari server kami di sisi kanan, yang akan terlihat seperti ini:

 { "data": { "users": [ { "id": "1", "email": "[email protected]", "name": "Carolyn Powlowski" }, { "id": "2", "email": "[email protected]", "name": "Elouise Raynor" }, { "id": "3", "email": "[email protected]", "name": "Mrs. Dejah Wiza" }, ... ] } }

Catatan: Karena kami menggunakan Faker untuk menyemai database kami, data di bidang email dan name akan berbeda.

Sekarang mari kita coba kueri untuk satu pengguna:

 { user(id: 1) { email name } }

Dan kita akan mendapatkan output berikut untuk satu pengguna:

 { "data": { "user": { "email": "[email protected]", "name": "Carolyn Powlowski" } } }

Meminta data seperti ini bagus untuk memulai, tetapi sangat kecil kemungkinannya Anda akan berada dalam proyek di mana Anda ingin menanyakan semua data Anda, jadi mari kita coba menambahkan beberapa pagination. Saat melihat melalui berbagai macam arahan bawaan Lighthouse, kami memiliki arahan @paginate yang tersedia untuk kami, jadi mari perbarui objek kueri skema kami seperti ini:

 type Query { user(id: ID! @eq): User @find users: [User!]! @paginate }

Jika kami memuat ulang GraphQL Playground ( Ctrl/Cmd + R ) dan mencoba kueri users kami lagi, Anda akan melihat bahwa kami mendapatkan pesan kesalahan yang menyatakan Cannot query field "id" on type "UserPaginator" , jadi apa yang terjadi? Di balik layar, Lighthouse memanipulasi skema kami agar kami mendapatkan serangkaian hasil yang diberi halaman dan melakukannya dengan mengubah jenis pengembalian bidang users kami.

Mari kita lihat lebih dekat dengan memeriksa skema kita di tab “Docs” GraphQL Playground. Jika Anda melihat bidang users , itu mengembalikan UserPaginator yang mengembalikan array pengguna dan jenis PaginatorInfo yang ditentukan Lighthouse:

 type UserPaginator { paginatorInfo: PaginatorInfo! data: [User!]! } type PaginatorInfo { count: Int! currentPage: Int! firstItem: Int hasMorePages: Boolean! lastItem: Int lastPage: Int! perPage: Int! total: Int! }

Jika Anda terbiasa dengan pagination bawaan Laravel, bidang yang tersedia dalam tipe PaginatorInfo mungkin akan terlihat sangat familier bagi Anda. Jadi, untuk meminta dua pengguna, mendapatkan jumlah total pengguna dalam sistem, dan memeriksa apakah kami memiliki lebih banyak halaman untuk digilir, kami akan mengirimkan kueri berikut:

 { users(count:2) { paginatorInfo { total hasMorePages } data { id name email } } }

Yang akan memberi kami respons berikut:

 { "data": { "users": { "paginatorInfo": { "total": 11, "hasMorePages": true }, "data": [ { "id": "1", "name": "Carolyn Powlowski", "email": "[email protected]" }, { "id": "2", "name": "Elouise Raynor", "email": "[email protected]" }, ] } } }

Hubungan

Umumnya, saat mengembangkan aplikasi, sebagian besar data Anda terkait. Dalam kasus kami, User dapat menulis banyak Articles , jadi mari tambahkan hubungan itu ke jenis Pengguna kami dan tentukan jenis Article kami:

 type User { id: ID! name: String! email: String! articles: [Article!]! @hasMany } type Article { id: ID! title: String! content: String! }

Di sini, kami menggunakan arahan skema lain yang disediakan Lighthouse @hasMany , yang memberi tahu Lighthouse bahwa model User kami memiliki hubungan \Illuminate\Database\Eloquent\Relations\HasMany dengan model Article .

Sekarang mari kita query hubungan kita yang baru didefinisikan:

 { user(id:1) { articles { id title } } }

Ini akan memberi kami respons berikut:

 { "data": { "user": { "articles": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint." }, { "id": "2", "title": "Voluptatem sed labore ea voluptas." }, { "id": "3", "title": "Beatae sit et maxime consequatur et natus totam." }, { "id": "4", "title": "Corrupti beatae cumque accusamus." }, { "id": "5", "title": "Aperiam quidem sit esse rem sed cupiditate." } ] } } }

Akhirnya, mari kita balikkan hubungan kita dan tambahkan hubungan author kita ke jenis objek Article kita menggunakan arahan skema @belongsTo Lighthouse serta memperbarui Query kita :

 type Article { id: ID! title: String! content: String! author: User! @belongsTo(relation: "user") } type Query { user(id: ID! @eq): User @find users: [User!]! @paginate article(id: ID! @eq): Article @find articles: [Article!]! @paginate }

Anda akan melihat bahwa kami menambahkan argumen relation opsional ke direktif @belongsTo . Ini memberitahu Lighthouse untuk menggunakan hubungan user model Articles dan menetapkannya ke bidang author .

Sekarang mari kita cari daftar artikel dan ambil penulis terkaitnya:

 { articles(count:2) { paginatorInfo { total hasMorePages } data { id title author { name email } } } }

Dan kita harus mendapatkan yang berikut dari server kami:

 { "data": { "articles": { "paginatorInfo": { "total": 55, "hasMorePages": true }, "data": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } }, { "id": "2", "title": "Voluptatem sed labore ea voluptas.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } } ] } } }

Mutasi GraphQL

Sekarang setelah kita dapat mengkueri data kita, mari buat beberapa mutasi untuk membuat beberapa pengguna dan artikel baru. Kami akan mulai dengan model pengguna kami:

 type Mutation { createUser( name: String! email: String! @rules(apply: ["email", "unique:users"]) password: String! @bcrypt @rules(apply: ["min:6"]) ): User @create }

Sekarang mari kita pecahkan definisi skema ini. Kami telah membuat mutasi yang disebut createUser yang mengambil tiga argumen ( name , email , dan password ). Kami telah menerapkan arahan @rules ke argumen email dan password kami. Ini mungkin terlihat agak familier karena mirip dengan logika validasi yang disediakan Laravel untuk pengontrolnya.

Selanjutnya, kami telah melampirkan arahan @bcrypt ke bidang password kami. Ini akan mengenkripsi kata sandi sebelum diteruskan ke model yang baru dibuat.

Terakhir, untuk membantu kami membuat model baru, Lighthouse menyediakan arahan skema @create yang akan mengambil argumen yang kami definisikan dan membuat model baru. Melakukan logika yang sama di Controller akan terlihat seperti berikut:

 namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Create a new user. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $data = $this->validate($request, [ 'email' => ['email', 'unique:users'], 'password' => ['min:6'] ]); $user = \App\User::create($data); return response()->json(['user' => $user]); } }

Sekarang setelah kita mengatur bidang mutasi createUser, mari kita lanjutkan dan jalankan di GraphQL Playground dengan yang berikut:

 mutation { createUser( name:"John Doe" email:"[email protected]" password: "secret" ) { id name email } }

Kita harus mendapatkan output berikut:

 { "data": { "createUser": { "id": "12", "name": "John Doe", "email": "[email protected]" } } }

Otentikasi dan Otorisasi GraphQL

Karena kita perlu menambahkan user_id ke model Article kita, sekarang adalah saat yang tepat untuk membahas otentikasi dan otorisasi di GraphQL/Lighthouse.

teks alternatif gambar

Untuk mengautentikasi pengguna, kita perlu menyediakan mereka dengan api_token , jadi mari buat mutasi untuk menanganinya dan kita akan menambahkan @field directive untuk mengarahkan Lighthouse ke resolver khusus yang akan menangani logika. Kami mengatur resolver dalam pola yang sama seperti mendefinisikan controller di Laravel menggunakan argumen resolver .

Dengan @field directive yang didefinisikan di bawah ini, kami memberi tahu Lighthouse ketika mutasi login dijalankan, gunakan metode createToken di kelas App\GraphQL\Mutations\AuthMutator :

 type Mutation { # ... login( email: String! password: String! ): String @field(resolver: "AuthMutator@resolve") }

Catatan: Anda tidak perlu menyertakan seluruh namespace di sini. Dalam file konfigurasi lighthouse.php Anda akan melihat kami memiliki namespace yang ditentukan untuk mutasi kami yang sudah ditetapkan sebagai App\\GraphQL\\Mutations —namun, Anda dapat menggunakan namespace lengkap jika Anda mau.

Mari gunakan generator Lighthouse untuk membuat kelas mutator baru:

 $ php artisan lighthouse:mutation AuthMutator

Selanjutnya, mari kita perbarui fungsi resolver kita seperti ini:

 namespace App\GraphQL\Mutations; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Facades\Auth; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class AuthMutator { /** * Return a value for the field. * * @param null $rootValue Usually contains the result returned from the parent field. In this case, it is always `null`. * @param mixed[] $args The arguments that were passed into the field. * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context Arbitrary data that is shared between all fields of a single query. * @param \GraphQL\Type\Definition\ResolveInfo $resolveInfo Information about the query itself, such as the execution state, the field name, path to the field from the root, and more. * @return mixed */ public function resolve($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) { $credentials = Arr::only($args, ['email', 'password']); if (Auth::once($credentials)) { $token = Str::random(60); $user = auth()->user(); $user->api_token = $token; $user->save(); return $token; } return null; } }

Sekarang setelah kita menyiapkan resolver, mari kita uji dan coba dapatkan token API menggunakan mutasi berikut di GraphQL Playground:

 mutation { login(email:"[email protected]", password:"secret") }

Kami harus mendapatkan token yang dikirim kembali kepada kami seperti:

 { "data": { "login": "VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" } }

Catatan: Pastikan untuk menyalin token yang dikembalikan dari mutasi login sehingga kami dapat menggunakannya nanti.

Selanjutnya, mari tambahkan bidang kueri yang akan mengembalikan pengguna yang diautentikasi untuk memastikan logika kita berfungsi. Kami akan menambahkan bidang yang disebut me dan menggunakan arahan @auth Lighthouse untuk mengembalikan pengguna yang saat ini diautentikasi. Kami juga akan menyetel argumen guard sama dengan api karena begitulah cara kami mengautentikasi pengguna.

 type Query { # ... me: User @auth(guard: "api") }

Sekarang mari kita jalankan kuerinya. Di GraphQL Playground, Anda dapat mengatur header permintaan Anda dengan mengklik dua kali tab "Http Header" di bagian bawah. Kami menambahkan header dengan objek JSON, jadi untuk menambahkan token pembawa ke setiap permintaan, Anda harus menambahkan yang berikut:

 { "Authorization": "Bearer VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" }

Catatan: Ganti token pembawa dengan token yang Anda terima saat menjalankan kueri login .

Sekarang mari kita jalankan kueri me :

 { me { email articles { id title } } }

Kita harus mendapatkan output yang terlihat seperti ini:

 { "data": { "me": { "email": "[email protected]", "articles": [ { "id": "1", "title": "Rerum perspiciatis et quos occaecati exercitationem." }, { "id": "2", "title": "Placeat quia cumque laudantium optio voluptatem sed qui." }, { "id": "3", "title": "Optio voluptatem et itaque sit animi." }, { "id": "4", "title": "Excepturi in ad qui dolor ad perspiciatis adipisci." }, { "id": "5", "title": "Qui nemo blanditiis sed fugit consequatur." } ] } } }

perangkat tengah

Sekarang setelah kita tahu otentikasi kita berfungsi dengan baik, mari buat mutasi terakhir kita untuk membuat artikel menggunakan pengguna yang saat ini diautentikasi. Kami akan menggunakan @field directive untuk mengarahkan Lighthouse ke resolver kami dan kami juga akan menyertakan @middleware directive untuk memastikan bahwa pengguna login.

 type Mutation { # ... createArticle(title: String!, content: String!): Article @field(resolver: "ArticleMutator@create") @middleware(checks: ["auth:api"]) }

Pertama, mari kita buat kelas mutasi:

 $ php artisan lighthouse:mutation ArticleMutator

Selanjutnya, mari kita perbarui mutator dengan logika berikut:

 namespace App\GraphQL\Mutations; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class ArticleMutator { /** * Return a value for the field. * * @param null $rootValue * @param mixed[] $args * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context * @return mixed */ public function create($rootValue, array $args, GraphQLContext $context) { $article = new \App\Article($args); $context->user()->articles()->save($article); return $article; } }

Catatan: Kami mengganti nama fungsi resolve default create . Anda tidak perlu membuat kelas baru untuk setiap resolver. Sebagai gantinya, Anda dapat mengelompokkan logika bersama jika lebih masuk akal.

Akhirnya, mari kita jalankan mutasi baru kita dan periksa hasilnya. Pastikan untuk menyimpan header Authorization dari kueri kami sebelumnya di tab "Header HTTP":

 mutation { createArticle( title:"Building a GraphQL Server with Laravel" content:"In case you're not currently familiar with it, GraphQL is a query language used to interact with your API..." ) { id author { id email } } }

Kita harus mendapatkan output berikut:

 { "data": { "createArticle": { "id": "56", "author": { "id": "1", "email": "[email protected]" } } } }

Membungkus

Untuk rekap, kami telah memanfaatkan Lighthouse untuk membuat server GraphQL untuk proyek Laravel kami. Kami menggunakan beberapa arahan skema bawaan, membuat kueri dan mutasi, dan menangani otorisasi dan Otentikasi.

Lighthouse memungkinkan Anda untuk melakukan lebih banyak (seperti memungkinkan Anda untuk membuat arahan skema kustom Anda sendiri) tetapi untuk tujuan artikel ini kami tetap berpegang pada dasar-dasar dan kami dapat membuat server GraphQL aktif dan berjalan dengan boilerplate yang cukup kecil.

Lain kali Anda perlu menyiapkan API untuk aplikasi seluler atau satu halaman, pastikan untuk mempertimbangkan GraphQL sebagai cara untuk menanyakan data Anda!

Terkait: Otentikasi Pengguna Penuh dan Kontrol Akses – Tutorial Paspor Laravel, Pt. 1