Laravel ile GraphQL Sunucusu Oluşturma
Yayınlanan: 2022-03-11Hala aşina değilseniz, GraphQL, API'nizle etkileşim kurmak için kullanılan ve REST gibi alternatif mimarilere kıyasla bazı avantajlar sağlayan bir sorgu dilidir. GraphQL, mobil ve tek sayfalık uygulamalar için bir uç nokta olarak kullanıldığında son derece kullanışlıdır. GraphQL, bir istekteki iç içe ve ilgili verileri nispeten kolaylıkla sorgulamanıza olanak tanır ve geliştiricilerin ihtiyaç duydukları tam verileri sunucuya tek bir gidiş dönüşte elde etmelerine olanak tanır.
Laravel, popüler, fikir sahibi bir PHP web çerçevesidir. Uygulamaları hızlı bir şekilde kurmak ve çalıştırmak için çok sayıda yerleşik araç sağlar, ancak aynı zamanda geliştiricilerin tercih edildiğinde kendi uygulamalarını Laravel'in yerleşik arabirimleriyle değiştirmelerine olanak tanır.
Hem GraphQL hem de Laravel'i çevreleyen topluluklar, açık kaynaklı olduklarından beri önemli ölçüde büyümüş olsa da, bu iki teknolojinin birlikte nasıl kullanılacağını açıklayan belgeler hala biraz azdır.
Bu derste size Laravel kullanarak kendi GraphQL sunucunuzu nasıl oluşturacağınızı göstereceğim.
Projeye Genel Bakış
Başlamadan önce, inşa etmeye çalıştığımız projeye aşina olmamız gerekecek. Bunu yapmak için kaynaklarımızı tanımlayacağız ve daha sonra API'mize hizmet etmek için kullanacağımız GraphQL şemamızı oluşturacağız.
Proje Kaynakları
Uygulamamız iki kaynaktan oluşacaktır: Makaleler ve Kullanıcılar . Bu kaynaklar, GraphQL şemamızda nesne türleri olarak tanımlanacaktır:
type User { id: ID! name: String! email: String! articles: [Article!]! } type Article { id: ID! title: String! content: String! author: User! }
Şemaya baktığımızda, iki nesnemiz arasında bire çok ilişkimiz olduğunu görebiliriz. Kullanıcılar birçok makale yazabilir ve bir makalenin kendisine atanmış bir yazarı (kullanıcısı) vardır.
Artık nesne türlerimizi tanımladığımıza göre, verilerimizi oluşturmak ve sorgulamak için bir yola ihtiyacımız olacak, o halde sorgu ve mutasyon nesnelerimizi tanımlayalım:
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 }
Laravel Projemizi Kurmak
GraphQL şemamızı tanımladığımıza göre, şimdi Laravel projemizi çalıştıralım. Composer projesi aracılığıyla yeni bir Laravel oluşturarak başlayalım:
$ composer create-project --prefer-dist laravel/laravel laravel-graphql
Her şeyin çalıştığından emin olmak için sunucumuzu başlatalım ve Laravel'in varsayılan sayfasını gördüğümüzden emin olalım:
$ cd laravel-graphql $ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
Veritabanı Modelleri ve Geçişler
Bu makalenin amaçları doğrultusunda SQLite kullanacağız. Öyleyse, varsayılan .env
dosyasında aşağıdaki değişiklikleri yapalım:
DB_CONNECTION=sqlite # DB_HOST= # DB_PORT= # DB_DATABASE=database.sqlite # DB_USERNAME= # DB_PASSWORD=
Ardından veritabanı dosyamızı oluşturalım:
$ touch ./database/database.sqlite
Laravel, bir kullanıcı modeli ve bazı temel geçiş dosyalarıyla birlikte gelir. Laravel tarafından bize sağlanan CreateUsersTable
taşıma dosyamıza hızlıca bir api_token
sütunu ekleyelim:
/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'); } }
Yetkilendirmeye geldiğimizde makalenin ilerleyen kısımlarında bu ek sütuna geri döneceğiz. Şimdi devam edelim ve ilgili tabloyu oluşturmak için makale modelimizi ve bir geçiş dosyası oluşturalım:
$ php artisan make:model Article -m
Not: -m seçeneği, yeni oluşturulan makale modelimiz için bir geçiş dosyası oluşturur.
Oluşturulan taşıma dosyasında bazı ayarlamalar yapalım:
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'); } }
GraphQL şemamızda tanımladığımız title
ve content
sütunlarının yanı sıra users
tablomuzdaki id
işaret eden bir yabancı anahtar ekledik.
Artık geçiş dosyalarımızı tanımladığımıza göre, devam edelim ve bunları veritabanımızda çalıştıralım:
$ php artisan migrate
Ardından, gerekli ilişkileri tanımlayarak modellerimizi güncelleyelim:
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); } }
Veritabanı Tohumlama
Artık modellerimizi ve geçişlerimizi ayarladığımıza göre, veritabanımızı tohumlayalım. articles
ve users
tablolarımız için bazı ekme sınıfları oluşturarak başlayacağız:
$ php artisan make:seeder UsersTableSeeder $ php artisan make:seeder ArticlesTableSeeder
Ardından, SQLite veritabanımıza bazı yapay veriler eklemek için bunları ayarlayalım:
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); } }
Son olarak, veri tabanımıza biraz veri almak için veri tabanı tohumlayıcılarımızı çalıştıralım:
$ php artisan db:seed
Laravel Lighthouse ve GraphQL Sunucusu
Artık veritabanımızı ve modellerimizi oluşturduğumuza göre, GraphQL sunucumuzu oluşturmaya başlamanın zamanı geldi. Şu anda Laravel için birkaç çözüm var, ancak bu makale için Lighthouse'u kullanacağız.
Lighthouse, birkaç yıl önce oluşturduğum bir paket ve son zamanlarda çevresinde büyüyen topluluktan inanılmaz bir destek gördü. Geliştiricilerin, hemen hemen her projenin gereksinimlerine uyacak şekilde özelleştirmesine izin verecek kadar esnek olmasının yanı sıra, küçük bir ortak plaka ile Laravel kullanarak bir GraphQL sunucusunu hızlı bir şekilde kurmalarına olanak tanır.
Paketi projemize çekerek başlayalım:
$ composer require nuwave/lighthouse:"3.1.*"
Ardından Lighthouse'un yapılandırma dosyasını yayınlayalım:
$ php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider" --tag=config
Not: Ayrıca, --tag=config
seçeneğini kaldırarak Lighthouse'un varsayılan şema dosyasını yayınlamayı da seçebilirsiniz. Ancak bu makalenin amaçları doğrultusunda şema dosyamızı sıfırdan oluşturacağız.
config/lighthouse.php
dosyasına bir göz atarsak, şema dosyamızı Lighthouse'a kaydetmek için kullanılan bir ayarı fark edeceksiniz:
'schema' => [ 'register' => base_path('graphql/schema.graphql'), ],
Öyleyse devam edelim ve şema dosyamızı oluşturalım ve kullanıcı nesne tipimizi ve sorgumuzu ayarlayalım:
$ 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 }
Şema yönergeleri adı verilen bazı tanımlayıcılar eklememiz dışında, şemamızın daha önce tanımladığımıza benzediğini fark edeceksiniz.
Tanımlanmış şemamızı parçalamak için bir dakikanızı ayıralım. İlk tanımımız, App\User
anlamlı modelimiz ile ilişkisi olan User
adlı bir nesne türüdür . User
modellerimizde sorgulanabilecek alanlar olarak id
, name
ve email
tanımladık. Alternatif olarak bu, password
, created_at
ve updated_at
sütunlarının API'mizden sorgulanamayan alanlar olduğu anlamına gelir.
Ardından, API'mize bir giriş noktası olan ve verileri sorgulamak için kullanılabilen Query
türümüz var. İlk alanımız, bir dizi User
nesne türü döndüren users
alanıdır. @all
yönergesi, Lighthouse'a User
modelimizi kullanarak bir Eloquent sorgusu çalıştırmasını ve tüm sonuçları almasını söyler. Bu, aşağıdakileri çalıştırmakla aynı olacaktır:
$users = \App\User::all();
Not: Lighthouse, yapılandırma dosyasında tanımlanan namespaces
seçeneği nedeniyle \App\User
ad alanında bir model aramayı bilir.
Sorgu tipimizde tanımlı ikinci alanımız, argüman olarak bir id
alan ve tek bir User
nesne tipi döndüren user
çağrısıdır. Ayrıca Lighthouse'un bizim için otomatik olarak bir sorgu oluşturmasına ve tek bir User
modeli döndürmesine yardımcı olmak için iki yönerge ekledik. @eq
yönergesi, Lighthouse'a id
sütunumuza bir yer eklemesini söyler ve @find
yönergesi, Lighthouse'a tek bir sonuç döndürmesini söyler. Bu sorguyu Laravel'in sorgu oluşturucusunu kullanarak yazmak için şöyle görünür:
$user = \App\User::where('id', $args['id'])->first();
GraphQL API'mizi Sorgulama
Artık Lighthouse'un sorgu oluşturmak için şemamızı nasıl kullandığına dair biraz bilgi sahibi olduğumuza göre, sunucumuzu çalıştıralım ve verileri sorgulamaya başlayalım. Sunucumuzu çalıştırarak başlayacağız:
$ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
Bir GraphQL uç noktasını sorgulamak için terminalde veya Postman gibi standart bir istemcide cURL komutunu çalıştırabilirsiniz. Ancak GraphQL'in tüm avantajlarından (otomatik tamamlama, hata vurgulama, belgeleme vb.) yararlanmak için GraphQL Playground'u kullanacağız (sürüm indirmeleri buradan).
Playground'u başlatırken, “URL Endpoint” sekmesine tıklayın ve GraphQL Playground'u sunucumuza yönlendirmek için http://localhost:8000/graphql yazın. Editörün sol tarafında, verilerimizi sorgulayabiliriz, bu yüzden veritabanını tohumladığımız tüm kullanıcıları sorarak başlayalım:
{ users { id email name } }
IDE'nin ortasındaki oynat düğmesine bastığınızda (veya Ctrl+Enter 'a tıkladığınızda), sağ tarafta sunucumuzun JSON çıktısını göreceksiniz, bu şuna benzer:
{ "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" }, ... ] } }
Not: Veritabanımızı tohumlamak için Faker'ı kullandığımız için email
ve name
alanlarındaki veriler farklı olacaktır.
Şimdi tek bir kullanıcı için sorgulamayı deneyelim:
{ user(id: 1) { email name } }
Ve tek bir kullanıcı için aşağıdaki çıktıyı alacağız:
{ "data": { "user": { "email": "[email protected]", "name": "Carolyn Powlowski" } } }
Bunun gibi verileri sorgulamaya başlamak güzeldir, ancak tüm verilerinizi sorgulamak isteyeceğiniz bir projede bulunmanız pek olası değildir, bu yüzden biraz sayfalandırma eklemeye çalışalım. Lighthouse'un çok çeşitli yerleşik direktiflerine bakarken, bizim için hazır bir @paginate
direktifimiz var, bu yüzden şemamızın sorgu nesnesini şu şekilde güncelleyelim:
type Query { user(id: ID! @eq): User @find users: [User!]! @paginate }
GraphQL Playground'u ( Ctrl/Cmd + R ) yeniden yüklersek ve users
sorgusunu tekrar denersek, Cannot query field "id" on type "UserPaginator"
şeklinde bir hata mesajı aldığımızı fark edeceksiniz, peki ne oldu? Perde arkasında, Lighthouse sayfalandırılmış bir sonuç kümesi elde etmemiz için şemamızı manipüle ediyor ve bunu users
alanımızın dönüş türünü değiştirerek yapıyor.

GraphQL Playground'un “Docs” sekmesindeki şemamızı inceleyerek daha yakından inceleyelim. users
alanına bakarsanız, bir dizi kullanıcı ve Lighthouse tanımlı PaginatorInfo
türü döndüren bir UserPaginator
döndürüyor:
type UserPaginator { paginatorInfo: PaginatorInfo! data: [User!]! } type PaginatorInfo { count: Int! currentPage: Int! firstItem: Int hasMorePages: Boolean! lastItem: Int lastPage: Int! perPage: Int! total: Int! }
Laravel'in yerleşik sayfalandırmasına aşina iseniz, PaginatorInfo
türünde bulunan alanlar muhtemelen size çok tanıdık gelecektir. Bu nedenle, iki kullanıcıyı sorgulamak, sistemdeki toplam kullanıcı sayısını almak ve geçiş yapacak daha fazla sayfamız olup olmadığını kontrol etmek için aşağıdaki sorguyu göndeririz:
{ users(count:2) { paginatorInfo { total hasMorePages } data { id name email } } }
Hangi bize aşağıdaki yanıtı sağlayacaktır:
{ "data": { "users": { "paginatorInfo": { "total": 11, "hasMorePages": true }, "data": [ { "id": "1", "name": "Carolyn Powlowski", "email": "[email protected]" }, { "id": "2", "name": "Elouise Raynor", "email": "[email protected]" }, ] } } }
ilişkiler
Genellikle, bir uygulama geliştirirken verilerinizin çoğu birbiriyle ilişkilidir. Bizim durumumuzda, bir User
birçok Articles
yazabilir, bu yüzden bu ilişkiyi Kullanıcı türümüze ekleyelim ve Article
türümüzü tanımlayalım:
type User { id: ID! name: String! email: String! articles: [Article!]! @hasMany } type Article { id: ID! title: String! content: String! }
Burada, Lighthouse'a User
modelimizin Article
modeliyle \Illuminate\Database\Eloquent\Relations\HasMany
ilişkisi olduğunu söyleyen başka bir Lighthouse tarafından sağlanan şema yönergesi @hasMany
kullanıyoruz.
Şimdi yeni tanımladığımız ilişkimizi sorgulayalım:
{ user(id:1) { articles { id title } } }
Bu bize aşağıdaki yanıtı verecektir:
{ "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." } ] } } }
Son olarak, Lighthouse'ın @belongsTo
şema yönergesini kullanarak ve Sorgumuzu güncelleyerek, ilişkimizi tersine Query
ve author
ilişkimizi Article
nesne türümüze ekleyelim:
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 }
@belongsTo
yönergesine isteğe bağlı bir relation
argümanı eklediğimizi göreceksiniz. Bu, Lighthouse'a Articles
modelinin user
ilişkisini kullanmasını ve bunu author
alanına atamasını söyler.
Şimdi bir makale listesi sorgulayalım ve ilgili yazarlarını alalım:
{ articles(count:2) { paginatorInfo { total hasMorePages } data { id title author { name email } } } }
Ve sunucumuzdan aşağıdakileri almalıyız:
{ "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]" } } ] } } }
GraphQL Mutasyonu
Artık verilerimizi sorgulayabileceğimize göre, bazı yeni kullanıcılar ve makaleler oluşturmak için bazı mutasyonlar oluşturalım. Kullanıcı modelimiz ile başlayacağız:
type Mutation { createUser( name: String! email: String! @rules(apply: ["email", "unique:users"]) password: String! @bcrypt @rules(apply: ["min:6"]) ): User @create }
Şimdi bu şema tanımını parçalayalım. Üç bağımsız değişken ( name
, email
ve password
) alan createUser
adında bir mutasyon yarattık. @rules
yönergesini hem email
hem de password
argümanlarımıza uyguladık. Bu biraz tanıdık gelebilir çünkü Laravel'in kontrolörleri için sağladığı doğrulama mantığına benzer.
Ardından, @bcrypt
yönergesini password
alanımıza ekledik. Bu, parolayı yeni oluşturulan modele geçmeden önce şifreleyecektir.
Son olarak, yeni modeller oluşturmamıza yardımcı olmak için Lighthouse, tanımladığımız argümanları alacak ve yeni bir model oluşturacak bir @create
schema yönergesi sağlar. Aynı mantığı bir Denetleyicide gerçekleştirmek aşağıdaki gibi görünecektir:
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]); } }
Artık createUser mutasyon alanımızı oluşturduğumuza göre, devam edelim ve GraphQL Playground'da aşağıdakilerle çalıştıralım:
mutation { createUser( name:"John Doe" email:"[email protected]" password: "secret" ) { id name email } }
Aşağıdaki çıktıyı almalıyız:
{ "data": { "createUser": { "id": "12", "name": "John Doe", "email": "[email protected]" } } }
GraphQL Kimlik Doğrulama ve Yetkilendirme
Article
modellerimize bir user_id
eklememiz gerektiğinden, şimdi GraphQL/Lighthouse'da kimlik doğrulama ve yetkilendirmeyi gözden geçirmek için harika bir zaman olacaktır.
Bir kullanıcının kimliğini doğrulamak için, onlara bir api_token
sağlamamız gerekiyor, bu yüzden bunu işlemek için bir mutasyon oluşturalım ve Lighthouse'u mantığı işleyecek özel bir çözümleyiciye yönlendirmek için @field
yönergesini ekleyeceğiz. Çözümleyiciyi, resolver
argümanını kullanarak Laravel'de bir denetleyici tanımlamayla aynı düzende ayarladık.
Aşağıda tanımlanan @field
yönergesiyle, login
mutasyonu çalıştırıldığında Lighthouse'a bildiriyoruz, App\GraphQL\Mutations\AuthMutator
sınıfımızda createToken
yöntemini kullanın:
type Mutation { # ... login( email: String! password: String! ): String @field(resolver: "AuthMutator@resolve") }
Not: Tüm ad alanını buraya eklemeniz gerekmez. lighthouse.php
yapılandırma dosyasında, mutasyonlarımız için zaten App\\GraphQL\\Mutations
olarak ayarlanmış ad alanına sahip olduğumuzu göreceksiniz - ancak isterseniz tam ad alanını kullanabilirsiniz.
Yeni mutator sınıfını oluşturmak için Lighthouse'ın oluşturucusunu kullanalım:
$ php artisan lighthouse:mutation AuthMutator
Ardından, çözümleyici işlevimizi şu şekilde güncelleyelim:
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; } }
Artık çözümleyicimizi kurduğumuza göre, test edelim ve GraphQL Playground'da aşağıdaki mutasyonu kullanarak bir API belirteci elde etmeye çalışalım:
mutation { login(email:"[email protected]", password:"secret") }
Bize şu şekilde geri gönderilen bir jeton almalıyız:
{ "data": { "login": "VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" } }
Not: Daha sonra kullanabilmemiz için oturum açma mutasyonundan döndürülen belirteci kopyaladığınızdan emin olun.
Ardından, mantığımızın çalıştığından emin olmak için kimliği doğrulanmış kullanıcıyı döndürecek bir sorgu alanı ekleyelim. me
adında bir alan ekleyeceğiz ve şu anda kimliği doğrulanmış kullanıcıyı döndürmek için Lighthouse'ın @auth
yönergesini kullanacağız. Ayrıca, kullanıcının kimliğini bu şekilde doğrulayacağımız için guard
argümanını api
eşitleyeceğiz.
type Query { # ... me: User @auth(guard: "api") }
Şimdi sorguyu çalıştıralım. GraphQL Playground'da, alttaki "Http Headers" sekmesine çift tıklayarak istek başlıklarınızı ayarlayabilirsiniz. Bir JSON nesnesiyle başlıklar ekliyoruz, bu nedenle her isteğe bir taşıyıcı belirteci eklemek için aşağıdakileri eklemeniz gerekir:
{ "Authorization": "Bearer VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" }
Not: Taşıyıcı belirteci, oturum açma sorgusunu çalıştırırken aldığınız belirteçle değiştirin.
Şimdi me
sorgusunu çalıştıralım:
{ me { email articles { id title } } }
Şuna benzeyen bir çıktı almalıyız:
{ "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." } ] } } }
ara katman yazılımı
Artık kimlik doğrulamamızın düzgün çalıştığını bildiğimize göre, şu anda kimliği doğrulanmış kullanıcıyı kullanarak bir makale oluşturmak için son mutasyonumuzu oluşturalım. Lighthouse'u çözümleyicimize yönlendirmek için @field
yönergesini kullanacağız ve ayrıca bir kullanıcının oturum açtığından emin olmak için bir @middleware
yönergesi ekleyeceğiz.
type Mutation { # ... createArticle(title: String!, content: String!): Article @field(resolver: "ArticleMutator@create") @middleware(checks: ["auth:api"]) }
İlk önce bir mutasyon sınıfı oluşturalım:
$ php artisan lighthouse:mutation ArticleMutator
Ardından, mutatörü aşağıdaki mantıkla güncelleyelim:
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; } }
Not: Varsayılan resolve
işlevini create
için yeniden adlandırdık. Her çözümleyici için yeni bir sınıf oluşturmanız gerekmez. Bunun yerine, daha mantıklı geliyorsa mantığı birlikte gruplayabilirsiniz.
Son olarak yeni mutasyonumuzu çalıştıralım ve çıktıyı kontrol edelim. "HTTP Başlıkları" sekmesindeki önceki sorgumuzun Authorization
başlığını sakladığınızdan emin olun:
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 } } }
Aşağıdaki çıktıyı almalıyız:
{ "data": { "createArticle": { "id": "56", "author": { "id": "1", "email": "[email protected]" } } } }
Toplama
Özetlemek gerekirse, Laravel projemiz için bir GraphQL sunucusu oluşturmak üzere Lighthouse'dan yararlandık. Bazı yerleşik şema yönergelerini kullandık, sorgular ve mutasyonlar oluşturduk ve yetkilendirme ve Kimlik Doğrulamayı ele aldık.
Lighthouse, çok daha fazlasını yapmanıza izin verir (örneğin, kendi özel şema yönergelerinizi oluşturmanıza izin vermek gibi), ancak bu makalenin amaçları doğrultusunda, temel bilgilere bağlı kaldık ve bir GraphQL sunucusunu oldukça küçük bir kalıp plakasıyla çalışır duruma getirmeyi başardık.
Bir dahaki sefere mobil veya tek sayfalık bir uygulama için bir API kurmanız gerektiğinde, verilerinizi sorgulamanın bir yolu olarak GraphQL'yi göz önünde bulundurduğunuzdan emin olun!