使用Lighthouse构建GraphQL API入门教程

使用Lighthouse构建GraphQL API入门教程

【免费下载链接】lighthouse A framework for serving GraphQL from Laravel 【免费下载链接】lighthouse 项目地址: https://gitcode.com/gh_mirrors/li/lighthouse

还在为REST API的版本管理、过度获取数据、接口冗余而烦恼吗?GraphQL作为新一代API查询语言,正在彻底改变我们构建API的方式。本文将带你从零开始,使用Lighthouse框架在Laravel中构建强大的GraphQL API,让你体验声明式数据查询的革命性优势。

为什么选择GraphQL + Lighthouse?

GraphQL核心优势

特性REST APIGraphQL
数据获取多个端点单个端点
请求响应固定结构按需获取
版本管理URL版本控制无版本中断
开发效率前后端耦合前后端分离

Lighthouse框架特色

Lighthouse是专为Laravel设计的GraphQL服务器框架,提供:

  • 零配置起步:内置默认Schema和解析器
  • Eloquent集成:无缝对接Laravel模型系统
  • 指令系统:丰富的内置指令简化开发
  • 类型安全:完整的GraphQL类型系统支持

环境准备与安装

系统要求

  • PHP 8.1+
  • Laravel 8.0+ 或 Lumen 8.0+
  • Composer

安装步骤

# 创建新的Laravel项目
composer create-project laravel/laravel graphql-api
cd graphql-api

# 安装Lighthouse
composer require nuwave/lighthouse

# 发布默认Schema
php artisan vendor:publish --tag=lighthouse-schema

# 生成IDE辅助文件
php artisan lighthouse:ide-helper

目录结构规划

mermaid

构建第一个GraphQL Schema

基础Schema定义

打开 graphql/schema.graphql 文件,让我们从简单的查询开始:

"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-05-23 13:43:32`."
scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")

type Query {
    "获取欢迎信息"
    hello: String! @field(resolver: "App\\GraphQL\\Queries\\Hello")
    
    "获取当前服务器时间"
    currentTime: DateTime!
}

type Mutation {
    "创建用户"
    createUser(
        name: String!
        email: String! @rules(apply: ["email"])
        password: String! @rules(apply: ["min:6"])
    ): User @create
}

"用户类型定义"
type User {
    id: ID!
    name: String!
    email: String!
    created_at: DateTime!
    updated_at: DateTime
}

创建解析器

使用Artisan命令快速生成解析器类:

php artisan lighthouse:query Hello

编辑生成的 app/GraphQL/Queries/Hello.php

<?php

namespace App\GraphQL\Queries;

final class Hello
{
    public function __invoke(): string
    {
        return '欢迎使用Lighthouse GraphQL API!';
    }
}

数据库模型与GraphQL集成

创建用户模型

php artisan make:model User -m

编辑数据库迁移文件:

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->timestamps();
    });
}

增强Schema功能

让我们扩展Schema以支持更复杂的操作:

type Query {
    # 用户查询
    users(
        name: String @where(operator: "like")
        email: String @where(operator: "like")
    ): [User!]! @paginate(defaultCount: 10)
    
    user(id: ID @eq): User @find
    
    # 高级查询示例
    activeUsers: [User!]! @all(model: "User", scopes: ["active"])
}

type Mutation {
    # 用户操作
    updateUser(
        id: ID!
        name: String
        email: String @rules(apply: ["email"])
    ): User @update
    
    deleteUser(id: ID!): User @delete
    
    # 批量操作
    createUsers(
        users: [CreateUserInput!]!
    ): [User!]! @create(model: "User")
}

input CreateUserInput {
    name: String!
    email: String! @rules(apply: ["email"])
    password: String! @rules(apply: ["min:6"])
}

实战:完整的用户管理系统

定义数据模型

在User模型中添加GraphQL相关配置:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
    
    /**
     * 获取GraphQL可查询的字段
     */
    public function graphqlFields(): array
    {
        return [
            'id',
            'name', 
            'email',
            'created_at',
            'updated_at'
        ];
    }
}

实现自定义解析器

创建复杂的业务逻辑解析器:

php artisan lighthouse:query UserStatistics
<?php

namespace App\GraphQL\Queries;

use App\Models\User;
use Illuminate\Support\Facades\DB;

final class UserStatistics
{
    public function __invoke($root, array $args): array
    {
        return [
            'total_users' => User::count(),
            'active_today' => User::whereDate('created_at', today())->count(),
            'by_month' => $this->getUsersByMonth(),
        ];
    }
    
    private function getUsersByMonth(): array
    {
        return User::select(
            DB::raw('YEAR(created_at) as year'),
            DB::raw('MONTH(created_at) as month'),
            DB::raw('COUNT(*) as count')
        )
        ->groupBy('year', 'month')
        ->orderBy('year', 'desc')
        ->orderBy('month', 'desc')
        ->get()
        ->toArray();
    }
}

完整的Schema示例

type Query {
    # 基础查询
    hello: String!
    currentTime: DateTime!
    
    # 用户查询
    users(
        name: String @where(operator: "like")
        email: String @where(operator: "like")
        created_after: DateTime @where(operator: ">=", key: "created_at")
        created_before: DateTime @where(operator: "<=", key: "created_at")
    ): [User!]! @paginate(defaultCount: 10)
    
    user(id: ID @eq): User @find
    
    # 统计查询
    userStatistics: UserStatistics! 
        @field(resolver: "App\\GraphQL\\Queries\\UserStatistics")
}

type Mutation {
    # 用户管理
    createUser(input: CreateUserInput! @spread): User! @create
    updateUser(id: ID!, input: UpdateUserInput! @spread): User! @update
    deleteUser(id: ID!): User! @delete
    
    # 批量操作
    bulkCreateUsers(input: [CreateUserInput!]!): [User!]! @create
}

type UserStatistics {
    total_users: Int!
    active_today: Int!
    by_month: [MonthlyStat!]!
}

type MonthlyStat {
    year: Int!
    month: Int!
    count: Int!
}

input CreateUserInput {
    name: String! @rules(apply: ["required", "min:2", "max:255"])
    email: String! @rules(apply: ["required", "email", "unique:users,email"])
    password: String! @rules(apply: ["required", "min:6"])
}

input UpdateUserInput {
    name: String @rules(apply: ["min:2", "max:255"])
    email: String @rules(apply: ["email", "unique:users,email"])
}

测试与验证

使用GraphiQL进行测试

安装GraphQL开发工具:

composer require mll-lab/laravel-graphiql

访问 /graphiql 即可开始测试:

# 查询示例
query GetUsers {
  users(first: 5) {
    data {
      id
      name
      email
      created_at
    }
    paginatorInfo {
      currentPage
      lastPage
      total
    }
  }
  
  userStatistics {
    total_users
    active_today
    by_month {
      year
      month
      count
    }
  }
}

# 变更示例
mutation CreateNewUser {
  createUser(input: {
    name: "张三"
    email: "zhangsan@example.com"
    password: "secret123"
  }) {
    id
    name
    email
    created_at
  }
}

自动化测试

创建GraphQL测试用例:

php artisan make:test GraphQLTest
<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class GraphQLTest extends TestCase
{
    use RefreshDatabase;

    public function test_hello_query()
    {
        $response = $this->graphQL('
            query {
                hello
            }
        ');

        $response->assertJson([
            'data' => [
                'hello' => '欢迎使用Lighthouse GraphQL API!'
            ]
        ]);
    }

    public function test_create_user_mutation()
    {
        $response = $this->graphQL('
            mutation {
                createUser(input: {
                    name: "测试用户",
                    email: "test@example.com", 
                    password: "password123"
                }) {
                    id
                    name
                    email
                }
            }
        ');

        $response->assertJson([
            'data' => [
                'createUser' => [
                    'name' => '测试用户',
                    'email' => 'test@example.com'
                ]
            ]
        ]);
        
        $this->assertDatabaseHas('users', [
            'email' => 'test@example.com'
        ]);
    }
}

性能优化与最佳实践

查询复杂度控制

type Query {
    users: [User!]! 
        @paginate(defaultCount: 10)
        @complexity(limit: 50)
}

type User {
    posts: [Post!]! 
        @hasMany
        @complexity(multipliers: ["first", "page"])
}

N+1查询解决方案

Lighthouse内置了DataLoader模式,自动批量处理关联查询:

type User {
    posts: [Post!]! @hasMany
    comments: [Comment!]! @hasMany
}

# 自动批量加载,避免N+1问题
query {
    users {
        name
        posts { title }
        comments { content }
    }
}

缓存策略

type Query {
    popularPosts: [Post!]! 
        @all
        @cache(maxAge: 3600) # 缓存1小时
        
    user(id: ID!): User 
        @find
        @cacheKey(attr: "id")
}

部署与监控

生产环境配置

// config/lighthouse.php
return [
    'route' => [
        'prefix' => 'api/graphql',
        'middleware' => ['api', 'auth:sanctum'],
    ],
    
    'cache' => [
        'enable' => env('LIGHTHOUSE_CACHE_ENABLE', true),
        'ttl' => env('LIGHTHOUSE_CACHE_TTL', 3600),
    ],
    
    'security' => [
        'max_query_complexity' => 100,
        'max_query_depth' => 10,
    ],
];

健康检查端点

type Query {
    health: HealthStatus!
}

type HealthStatus {
    status: String!
    timestamp: DateTime!
    database: Boolean!
    cache: Boolean!
    queue: Boolean!
}

总结与展望

通过本教程,你已经掌握了使用Lighthouse构建GraphQL API的核心技能:

环境搭建:快速安装配置Lighthouse框架
Schema设计:掌握GraphQL类型系统和查询语言
数据操作:实现CRUD操作和复杂查询
性能优化:利用内置功能避免常见性能问题
测试部署:确保API的可靠性和稳定性

GraphQL正在成为现代API开发的标准,而Lighthouse让Laravel开发者能够轻松拥抱这一变革。无论是构建微服务架构、移动应用后端还是复杂的Web应用,GraphQL都能提供更好的开发体验和性能表现。

下一步,你可以探索Lighthouse的更多高级特性:

  • 实时订阅:使用WebSocket实现实时数据推送
  • 联邦架构:构建微服务GraphQL生态系统
  • 自定义指令:扩展GraphQL schema的功能
  • 性能监控:集成APM工具进行性能分析

开始你的GraphQL之旅,体验声明式API开发的强大魅力吧!

【免费下载链接】lighthouse A framework for serving GraphQL from Laravel 【免费下载链接】lighthouse 项目地址: https://gitcode.com/gh_mirrors/li/lighthouse

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值