Laravel中使用Lighthouse在GraphQL访问点传参及数据库切换问题
在Laravel Lighthouse中获取URL查询参数并切换数据库
问题根源
Lighthouse默认不会自动将URL查询参数注入到GraphQL上下文或Resolver中,同时全局数据库连接切换需要在请求生命周期内提前处理。以下是两种场景的解决方案:
场景1:仅全局切换数据库(无需在Resolver中使用参数)
直接通过Laravel中间件读取URL参数并切换数据库,无需修改GraphQL上下文:
- 创建数据库切换中间件
新建app/Http/Middleware/SwitchDatabaseBasedOnParam.php:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class SwitchDatabaseBasedOnParam { public function handle(Request $request, Closure $next) { // 读取URL中的development参数 $isDevelopment = $request->query('development') === 'true'; // 切换对应数据库连接(需在config/database.php中配置development连接) $targetConnection = $isDevelopment ? 'development' : 'mysql'; DB::setDefaultConnection($targetConnection); return $next($request); } public function terminate(Request $request, $response) { // 请求结束后恢复默认数据库连接,避免污染后续请求 DB::setDefaultConnection('mysql'); } }
- 注册中间件
在app/Http/Kernel.php的api中间件组中添加该中间件:
protected $middlewareGroups = [ 'api' => [ // ...其他已存在的中间件 \App\Http\Middleware\SwitchDatabaseBasedOnParam::class, ], ];
场景2:需要在GraphQL Resolver中访问参数
如果需要在Resolver逻辑中使用development参数,需先将参数注入GraphQL上下文:
- 创建上下文注入中间件
新建app/Http/Middleware/InjectGraphQLQueryParams.php:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class InjectGraphQLQueryParams { public function handle(Request $request, Closure $next) { if ($request->is('graphql')) { // 将URL查询参数合并到Lighthouse上下文 $request->request->add([ 'context' => array_merge( $request->request->get('context', []), ['query_params' => $request->query()] ) ]); } return $next($request); } }
注册中间件
同样在app/Http/Kernel.php的api组中注册该中间件。在Resolver中读取参数
在自定义Resolver中通过上下文获取参数:
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; public function resolve($root, array $args, GraphQLContext $context) { $isDevelopment = $context->query_params['development'] === 'true'; // 根据参数执行对应逻辑,比如动态切换模型的数据库连接 if ($isDevelopment) { $model = (new YourModel())->setConnection('development'); } else { $model = new YourModel(); } return $model->all(); }
验证方式
访问{url}/graphql?development=true后,可通过以下方式验证:
- 全局切换场景:在数据库查询日志中查看使用的连接名称
- Resolver场景:在Resolver中输出参数值确认是否获取成功
内容的提问来源于stack exchange,提问作者Arfat Mughal
相关产品推荐
相关产品推荐

