· Admin

Laravel ile GraphQL API Geliştirme

REST API'de her endpoint sabit bir veri yapısı döner — ihtiyacınızdan fazlasını veya azını alırsınız. GraphQL ise istemcinin "sadece ihtiyacım olan veriyi ver" demesine izin veriyor. Facebook tarafından geliştirildi ve 2015'ten beri açık kaynak.

GraphQL vs REST

Özellik REST GraphQL
Endpoint Her resource için ayrı Tek endpoint
Veri miktarı Over/under fetching Tam ihtiyaç kadar
Versiyon v1, v2, v3... Gereksiz
Dokümantasyon Swagger/OpenAPI Schema kendisi dokümantasyon
Öğrenme eğrisi Düşük Orta

Laravel'de GraphQL Kurulumu

composer require rebing/graphql-laravel
php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"

Bu işlemle config/graphql.php oluşur.

Type Tanımlama

Her veri yapısı için bir Type sınıfı oluşturulur:

namespace App\GraphQL\Types;

use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Type as GraphQLType;

class UserType extends GraphQLType
{
    protected $attributes = [
        'name' => 'User',
        'description' => 'Kullanıcı veri tipi',
    ];

    public function fields(): array
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::int()),
            ],
            'name' => [
                'type' => Type::string(),
            ],
            'email' => [
                'type' => Type::string(),
            ],
            'created_at' => [
                'type' => Type::string(),
            ],
        ];
    }
}

Query (Okuma)

namespace App\GraphQL\Queries;

use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Query;
use App\Models\User;

class UsersQuery extends Query
{
    protected $attributes = [
        'name' => 'users',
    ];

    public function type(): Type
    {
        return Type::listOf(\GraphQL::type('User'));
    }

    public function resolve($root, $args)
    {
        return User::all();
    }
}

Tek kullanıcı sorgusu:

class UserQuery extends Query
{
    protected $attributes = [
        'name' => 'user',
    ];

    public function type(): Type
    {
        return \GraphQL::type('User');
    }

    public function args(): array
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::int()),
            ],
        ];
    }

    public function resolve($root, $args)
    {
        return User::findOrFail($args['id']);
    }
}

Mutation (Yazma)

namespace App\GraphQL\Mutations;

use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Mutation;
use App\Models\User;

class CreateUserMutation extends Mutation
{
    protected $attributes = [
        'name' => 'createUser',
    ];

    public function type(): Type
    {
        return \GraphQL::type('User');
    }

    public function args(): array
    {
        return [
            'name' => [
                'type' => Type::nonNull(Type::string()),
            ],
            'email' => [
                'type' => Type::nonNull(Type::string()),
                'rules' => ['email', 'unique:users'],
            ],
            'password' => [
                'type' => Type::nonNull(Type::string()),
                'rules' => ['min:8'],
            ],
        ];
    }

    public function resolve($root, $args)
    {
        return User::create([
            'name' => $args['name'],
            'email' => $args['email'],
            'password' => bcrypt($args['password']),
        ]);
    }
}

Konfigürasyon

config/graphql.php:

'schemas' => [
    'default' => [
        'query' => [
            'users' => App\GraphQL\Queries\UsersQuery::class,
            'user' => App\GraphQL\Queries\UserQuery::class,
        ],
        'mutation' => [
            'createUser' => App\GraphQL\Mutations\CreateUserMutation::class,
        ],
        'types' => [
            'User' => App\GraphQL\Types\UserType::class,
        ],
    ],
],

Sorgu Örnekleri

GraphQL endpoint: POST /graphql

Kullanıcı listesi (sadece id ve name):

{
    users {
        id
        name
    }
}

Tek kullanıcı (tüm alanlar):

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

Yeni kullanıcı oluşturma:

mutation {
    createUser(name: "Ali", email: "[email protected]", password: "12345678") {
        id
        name
        email
    }
}

İlişkili Veriler

GraphQL'in en güçlü yanı — ilişkili verileri tek sorguda alma:

// PostType
public function fields(): array
{
    return [
        'id' => ['type' => Type::int()],
        'title' => ['type' => Type::string()],
        'author' => [
            'type' => \GraphQL::type('User'),
            'resolve' => fn ($post) => $post->author,
        ],
    ];
}
{
    posts {
        title
        author {
            name
        }
    }
}

Tek sorguda post ve author — REST'te iki ayrı istek gerekir.

GraphQL'in Avantajları

  • Esneklik: İstemci ne isterse onu alır
  • Tek endpoint: /graphql — yüzlerce endpoint yerine
  • Daha az veri transferi: Mobile uygulamalar için kritik
  • Otomatik dokümantasyon: Schema kendisi dokümantasyon

Ne Zaman GraphQL?

Uygun: Karmaşık veri ilişkileri, mobil uygulamalar, mikro-frontend'ler, birden fazla istemci tipi.

Uygun değil: Basit CRUD, dosya upload ağırlıklı API'ler, gerçek zamanlı streaming (bunun için WebSocket daha iyi).

Sonuç

GraphQL, REST'in sınırlamalarını aşan modern bir API yaklaşımı. Laravel ile rebing/graphql-laravel paketi sayesinde hızlıca kurulabiliyor. Ama her proje için şart değil — basit API'lerde REST yeterli ve daha basit.