Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇 | 构建 API 接口:GraphQL | Laravel 入门到精通教程


本站和网页 https://xueyuanjun.com/post/9251.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇 | 构建 API 接口:GraphQL | Laravel 入门到精通教程
Laravel 学院
文档
Laravel 8.x 中文文档
Laravel 7.x 中文文档
Laravel 6.x 中文文档
Laravel 5.8 中文文档
Laravel 5.7 中文文档
Laravel 5.6 中文文档
Laravel 5.5 中文文档
Laravel 5.4 中文文档
Laravel 5.3 中文文档
Laravel 5.2 中文文档
Laravel 5.1 中文文档
Lumen 中文文档
全栈教程
PHP 全栈工程师指南
PHP 入门到实战
Laravel 入门到精通
Vue.js 入门到实战
玩转 PhpStorm 教程
Laravel 博客入门项目
Laravel 微信小程序项目
Laravel 前后端分离项目
Swoole 入门到实战
Eloquent 性能优化实战
Redis 高性能实战系列
Laravel 新版本特性
PHP 新特性与最佳实践
Golang
Go 入门教程
Go Web 编程
Gin 使用教程
微服务开发
内功修炼
数据结构与算法
网络协议
微服务从入门到实践
高性能 MySQL 实战
高性能 Redis 实战
Laravel 消息队列实战
Laravel 从学徒到工匠
PHP 设计模式系列
名企面试指南
资源库
Laravel 资源大全
Laravel 开源项目
Laravel 扩展包
Laravel 资源下载
更多
博客 & 新闻
问答 & 讨论
Leetcode 题解
学院君读书笔记系列
关于 Laravel 学院
Laravel 互助学习群
Golang 互助学习群
更多
Laravel 中文文档
Laravel 全栈教程
Laravel 学习路径
Go 入门教程
程序员内功修炼
博客
问答
搜索
注册
登录
Info
Content
章节导航
Laravel 入门到精通教程
目录索引
开发环境篇
8篇文章
通过 Sail 构建基于 Docker 的 Laravel 本地集成开发环境
通过 Homestead 构建基于 Vagrant 的 Laravel 本地集成开发环境
通过 Valet 在 Mac 系统构建轻量级 Laravel 本地集成开发环境
Mac 系统为 Valet 开发环境安装指定版本 MySQL
在 Mac/Windows 系统中使用 Laradock 搭建基于 Docker 的 Laravel 开发环境
使用 Laragon 在 Windows 中快速搭建 Laravel 本地开发环境
使用 Visual Studio Code 作为 Laravel 开发工具
创建并运行一个新的 Laravel 项目
路由&控制器篇
5篇文章
Laravel 路由入门:路由定义、参数传递及路由命名
Laravel 路由分组规则:中间件、子域名、路由前缀和命名空间
Laravel 控制器:从 MVC 模式到资源控制器
路由进阶使用:模型绑定、兜底路由、频率限制和路由缓存
表单方法伪造与跨站请求伪造(CSRF)攻击防护
视图模板篇
4篇文章
视图入门:Laravel 支持的视图格式以及在路由中的基本使用
Blade 模板引擎入门篇:数据渲染 & 控制结构
Blade 模板引擎进阶篇:模板继承 & 组件引入
Blade 模板引擎高级篇:View Composer & 自定义指令
前端入门篇
3篇文章
在 Laravel 项目中使用 Bootstrap 框架
CSS 预编译语言 Sass 快速入门教程
在 Laravel 项目中编写第一个 Vue 组件
请求处理篇
5篇文章
通过 Request 对象实例获取用户请求数据
基于 Laravel + Vue 组件实现文件异步上传
在 Laravel 控制器中进行表单请求字段验证
通过表单请求类实现请求字段验证和错误提示
通过匿名函数和验证规则类自定义字段验证规则
命令行交互篇
3篇文章
在 Laravel 中编写第一个 Artisan 命令
在 Laravel 中编写高级的 Artisan 命令
通过 Tinker 实现 Laravel 命令行交互式 Shell
数据库与 Eloquent 模型
16篇文章
入门篇(一):数据库连接配置和读写分离
入门篇(二):通过迁移文件定义数据表结构
入门篇(三):通过填充器快速填充测试数据
入门篇(四):通过查询构建器实现简单的增删改查操作
进阶篇(一):通过查询构建器实现复杂的查询语句
进阶篇(二) —— 通过 Eloquent 模型实现简单增删改查操作
进阶篇(三):通过 Eloquent 模型实现批量赋值和软删除
进阶篇(四):在 Eloquent 模型类上设置访问器和修改器
进阶篇(五):在 Eloquent 模型类上使用全局作用域和局部作用域进行查询
进阶篇(六):Eloquent 模型事件和监听方式大全
进阶篇(七):Eloquent 模型关联关系(上)
进阶篇(八):Eloquent 模型关联关系(中)
进阶篇(九):Eloquent 模型关联关系(下)
结合 Bootstrap + Vue 组件在 Laravel 中实现异步分页功能
在 Laravel 中通过自定义分页器分页方法实现伪静态分页链接以利于 SEO
基于 Laravel + Vue 构建一个类似 Twitter 的 Web 应用
用户认证与授权
19篇文章
使用 Entrust 扩展包在 Laravel 5 中实现 RBAC 权限管理(一):安装配置篇
使用 Entrust 扩展包在 Laravel 5 中实现 RBAC 权限管理(二):使用篇
基于 Laravel Permission 扩展包在项目中轻松实现 RBAC 权限管理功能
通过内置脚手架快速实现用户认证
用户注册登录流程及多字段登录实现
基于多表的用户认证功能实现(前后台用户)
通过 Passport 实现 API 请求认证:单页面应用篇
通过 Passport 实现 API 请求认证:移动端应用篇(密码授权令牌)
通过 Passport 实现 API 请求认证:第三方应用篇(授权码获取令牌)
通过 Passport 实现 API 请求认证:开放平台篇(客户端凭证令牌)
通过 Passport 实现 API 请求认证:沙箱测试篇(私人访问令牌)
通过 Passport 实现 API 请求认证:隐式授权令牌
通过 Passport 实现 API 请求认证:令牌作用域详解
通过 Laravel 内置脚手架快速实现邮箱验证功能
通过监听注册登录、邮箱验证事件实现简单的积分功能
通过 Cookie 实现基于 Session 的单点登录
基于 CAS 实现通用的单点登录解决方案(一):CAS 原理及服务端搭建
基于 CAS 实现通用的单点登录解决方案(二):CAS 客户端搭建及单点登录测试
基于 CAS 实现通用的单点登录解决方案(三):用户单点退出实现
请求响应底层剖析
8篇文章
Laravel 底层是如何处理 HTTP 请求的
Laravel 请求类 Request 剖析
Laravel 响应类 Response 剖析
Laravel 中间件底层源码剖析
Laravel 路由匹配和执行底层源码剖析
异常处理篇之底层源码剖析
异常处理篇之异常信息报告、渲染及自定义处理
Laravel 框架如何基于 Composer 实现类和文件的自动加载
测试驱动开发
12篇文章
从基于 PHPUnit 编写单元测试开始
在 Laravel 中基于 PHPUnit 进行代码测试:目录结构及测试编排文件 phpunit.xml 详解
在 Laravel 中基于 PHPUnit 进行代码测试:单元测试篇
在 Laravel 中基于 PHPUnit 进行代码测试:HTTP 测试篇(上)
在 Laravel 中基于 PHPUnit 进行代码测试:HTTP 测试篇(下)
在 Laravel 中基于 Dusk 实现浏览器自动化测试快速入门
通过测试驱动开发构建待办任务项目(一):后端接口和功能测试篇
通过测试驱动开发构建待办任务项目(二):前端功能和浏览器测试篇
持续集成的定义和常用 CI 系统对比
基于 Github + CircleCI 实现 Laravel 项目的持续集成
基于 Github + Travis CI 实现 Laravel 项目的持续集成
基于 Coding + Jenkins 实现 Laravel 项目的持续集成
构建 API 接口:原生开发
5篇文章
编写 JSON API —— RESTful 风格 API 设计原则与最佳实践
编写 JSON API —— 基于资源控制器和 API 资源类快速构建 API 接口
Laravel API 系列教程(一): 基于 Laravel 5.5 构建 & 测试 RESTful API
Laravel API 系列教程(二): 结合 Laravel 5.5 和 Vue SPA 基于 jwt-auth 实现 API 认证
Laravel API 系列教程(三):使用 API Resource 来创建自己的 {JSON:API} 格式 API
构建 API 接口:GraphQL
6篇文章
Laravel API 系列教程(四):基于 GraphQL 构建 Laravel API —— 基本使用篇
Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇
解决前后端分离应用跨域请求利器 —— Laravel CORS 扩展包
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(二) —— 用户列表及详情页
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(三) —— 文章发布及浏览
构建 API 接口:Dingo API
12篇文章
使用 Dingo API 快速构建 RESTful API(一)—— 安装配置篇
使用 Dingo API 快速构建 RESTful API(二)—— 编写第一个 API 接口
使用 Dingo API 快速构建 RESTful API(三)—— 返回基本 JSON 响应
使用 Dingo API 快速构建 RESTful API(四)—— 转化器篇(上):Fractal 简介及其使用入门
使用 Dingo API 快速构建 RESTful API(五)—— 转化器篇(下):结合响应构建器构建 JSON 响应
使用 Dingo API 快速构建 RESTful API(六)—— 转化器及响应构建器的高级使用
使用 Dingo API 快速构建 RESTful API(七)—— 错误及异常处理
使用 Dingo API 快速构建 RESTful API(八)—— API 认证实现(上)
使用 Dingo API 快速构建 RESTful API(九)—— API 认证实现(下)
使用 Dingo API 快速构建 RESTful API(十)—— 路由访问频率限制
使用 Dingo API 快速构建 RESTful API(十一)—— 在应用内部请求 Dingo API
使用 Dingo API 快速构建 RESTful API(十二)—— 生成 API 文档
构建 API 接口:生成 API 文档
3篇文章
使用 Laravel API 文档生成器扩展包自动为项目生成 API 文档
在 Laravel 中集成 API 文档生成器扩展包为 Dingo API 接口生成文档
在 Laravel 项目中集成 Swagger 扩展包为 Laravel API 生成接口文档并对接口进行测试
系统组件
4篇文章
基于 Laravel + Pusher + Vue 通过事件广播构建实时聊天室应用
由浅入深:基于 Laravel Broadcast 实现 WebSocket C/S 实时通信
基于迅搜(xunsearch) + Laravel Scout 实现 Laravel 学院全文搜索功能(支持多模型搜索)
基于七牛云 PHP SDK + Laravel 文件存储实现 Laravel 学院静态资源云存储及 CDN 加速
图书
Laravel 入门到精通教程
构建 API 接口:GraphQL
Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇
Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇
由 学院君 创建于4年前, 最后更新于 2年前
版本号 #3
20089 views
3 likes
1 collects
上一篇教程中我们重点探讨了 GraphQL 的概念及其在 Laravel API 构建中的基本使用,本篇教程将在其基础上探讨关于 GraphQL 的一些更高级的使用。
带参数的查询
带参数的查询是构建 API 时的常见操作,上一篇教程中编写的列表查询功能已经支持带参数查询,只需传入相应查询参数即可:
嵌套资源
关联关系是 Laravel 模型操作中又一重要功能,我们可以通过关联关系获取嵌套资源。在 User 模型中定义用户与评论的关联关系如下:
public function comments()
return $this->hasMany(Comment::class, 'user_id', 'id');
然后创建 CommentType 类型:
php artisan make:graphql:type CommentType
编辑新生成的 CommentType 类:
namespace App\GraphQL\Type;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as BaseType;
use GraphQL;
class CommentType extends BaseType
protected $attributes = [
'name' => 'Comment',
'description' => 'A Comment'
];
public function fields()
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the comment'
],
'content' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The content of the comment'
];
接下来在配置文件 config/graphql.php 中注册这个类型:
'types' => [
...
'Comment' => \App\GraphQL\Type\CommentType::class,
],
最后在 UserType 中新增 comments 字段及对应解析方法:
public function fields()
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'email' => [
'type' => Type::string(),
'description' => 'The email of the user'
],
'comments' => [
'type' => Type::listOf(GraphQL::type('Comment')),
'description' => 'The comments by the user'
];
...
protected function resolveCommentsField($root, $args)
if (isset($args['id'])) {
return $root->comments->where('id', $args['id']);
return $root->comments;
这样,我们就可以通过 GraphiQL 演示嵌套资源的获取了:
枚举
这里的枚举和我们在编程语言中的枚举概念一样,要使用枚举,可以通过以下 Artisan 命令创建一个 CommentStatusEnum 类:
php artisan make:graphql:enum CommentStatusEnum
编辑新生成的 CommentStatusEnum 类:
namespace App\GraphQL\Enums;
use Folklore\GraphQL\Support\EnumType;
class CommentStatusEnum extends EnumType
protected $enumObject = true;
protected $attributes = [
'name' => 'CommentStatus',
'description' => 'Comment status enum'
];
public function values() {
return [
'APPROVED' => '1',
'REJECT' => '0'
];
然后在配置文件 config/graphql.php 中注册这个枚举类型:
'types' => [
...
'CommentStatusEnum' => \App\GraphQL\Enums\CommentStatusEnum::class
],
最后在 CommentType 中新增 status 字段:
public function fields()
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the comment'
],
'content' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The content of the comment'
],
'status' => [
'type' => GraphQL::type('CommentStatusEnum'),
'description' => 'The status of the comment'
];
这样就可以在 GraphiQL 中演示枚举功能的使用了:
接口
GraphQL 中的接口和面向对象编程语言中的接口(Laravel中叫契约)作用类似,只不过是用来约束一组相关类型必须实现的方法。我们可以通过 Artisan 命令生成接口:
php artisan make:graphql:interface CharacterInterface
编辑刚刚生成的 CharacterInterface 接口代码:
// app/GraphQL/Interfaces/CharacterInterface.php
namespace App\GraphQL\Interfaces;
use GraphQL;
use Folklore\GraphQL\Support\InterfaceType;
use GraphQL\Type\Definition\Type;
class CharacterInterface extends InterfaceType {
protected $attributes = [
'name' => 'Character',
'description' => 'Character interface.',
];
public function fields() {
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => 'The id of the character.'
],
'appearsIn' => [
'type' => Type::nonNull(Type::listOf(GraphQL::type('Episode'))),
'description' => 'A list of episodes in which the character has an appearance.'
],
];
public function resolveType($root) {
// Use the resolveType to resolve the Type which is implemented trough this interface
$type = $root['type'];
if ($type === 'human') {
return GraphQL::type('Human');
} else if ($type === 'droid') {
return GraphQL::type('Droid');
然后我们来定义一个实现该接口的子类型 HumanType(自行通过 Artisan 命令生成),需要注意的是这里对接口的实现并不是通过 implement 关键字,而是通过 interfaces() 方法:
// app/GraphQL/Types/HumanType.php
namespace App\GraphQL\Types;
use GraphQL;
use Folklore\GraphQL\Support\Type as GraphQLType;
use GraphQL\Type\Definition\Type;
class HumanType extends GraphQLType {
protected $attributes = [
'name' => 'Human',
'description' => 'A human.'
];
public function fields() {
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => 'The id of the human.',
],
'appearsIn' => [
'type' => Type::nonNull(Type::listOf(GraphQL::type('Episode'))),
'description' => 'A list of episodes in which the human has an appearance.'
],
'totalCredits' => [
'type' => Type::nonNull(Type::int()),
'description' => 'The total amount of credits this human owns.'
];
public function interfaces() {
return [
GraphQL::type('Character')
];
自定义字段
除了 GraphQL 自带的常用字段外,对于一些复杂类型的字段,我们还可以基于 GraphQL 提供的接口进行扩展来实现。首先,创建一个自定义字段类:
php artisan make:graphql:field PictureField
然后编辑刚生成的 PictureField 类:
// app/GraphQL/Fields/PictureField
namespace App\GraphQL\Fields;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Field;
class PictureField extends Field {
protected $attributes = [
'description' => 'A picture'
];
public function type(){
return Type::string();
public function args()
return [
'width' => [
'type' => Type::int(),
'description' => 'The width of the picture'
],
'height' => [
'type' => Type::int(),
'description' => 'The height of the picture'
];
protected function resolve($root, $args)
$width = isset($args['width']) ? $args['width']:100;
$height = isset($args['height']) ? $args['height']:100;
return 'http://placehold.it/'.$width.'x'.$height;
最后我们在 UserType 中新增一个 picture 字段来使用这个自定义字段:
// app/GraphQL/Type/UserType
namespace App\GraphQL\Type;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
use App\GraphQL\Fields\PictureField;
class UserType extends GraphQLType {
protected $attributes = [
'name' => 'User',
'description' => 'A user'
];
public function fields()
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'email' => [
'type' => Type::string(),
'description' => 'The email of user'
],
'picture' => PictureField::class
];
渴求式加载
为提升查询效率,还可以在关联查询中使用渴求式加载。编辑 UserQuery 的 resolve 方法:
public function resolve($root, $args, $context, ResolveInfo $info)
$fields = $info->getFieldSelection($depth = 3);
if (isset($args['id'])) {
$users = User::where('id', $args['id']);
} elseif (isset($args['email'])) {
$users = User::where('email', $args['email']);
} else {
$users = User::query();
foreach ($fields as $field => $keys) {
if ($field === 'comments') {
$users->with('comments');
return $users->get();
然后在 GraphiQL 演示该功能:
基于 jwt-auth 实现接口认证
在 Laravel API 系列二教程中我们已经演示了如何基于 jwt-auth 实现接口认证,这里我们将在那篇教程基础上进行编码。API 首次认证成功后,我们通过在每次请求时传递 Authorization: Bearer {yourtokenhere} 请求头的方式实现后续认证。
以 UpdateUserPasswordMutation 为例,要让该操作认证后才能操作,可以在该方法中重写父类的 authenticate 方法:
public function authenticated($root, $args, $context)
return JWTAuth::parseToken()->authenticate() ? true : false;
这样,再次通过 GraphiQL 访问时就会报错:
而认证通过后(参考系列二教程实现)即可更新成功(Token 值通过在浏览器登录成功后在请求头中获取):
授权操作也是类似,我们需要覆盖父类的 authorize 来实现自定义的授权逻辑,感兴趣的同学可以试下。更多关于 GraphQL 在 Laravel API 中的使用请参考本系列教程使用的 Github 项目 folklore/graphql 以及 GraphQL 官方文档。
下一篇我们将讨论如何在 Vue 前端应用中访问基于 GraphQL 构建的 Laravel API 接口。
Laravel
查询
渴求式加载
自定义
认证
API
JWT
接口
5.5
请求参数
关联查询
GraphQL
枚举
点赞
取消点赞
收藏
取消收藏
赞赏
分享到以下平台:
<< 上一篇:
Laravel API 系列教程(四):基于 GraphQL 构建 Laravel API —— 基本使用篇
>> 下一篇:
解决前后端分离应用跨域请求利器 —— Laravel CORS 扩展包
8 条评论
#1
bigrocs
评论于 4年前
正在删除评论...
老大可以讲下scalar 的使用 如果请求返回对应字段是 对象数组就一定会用到
#2
范闲
评论于 4年前
正在删除评论...
爽了前端,后端呵呵。
#3
Gebiw
评论于 4年前
正在删除评论...
分页来怎么来做
#4
q569608465
评论于 4年前
正在删除评论...
文件上传GraphQL 怎么实现
#5
zxg321
评论于 4年前
正在删除评论...
分页见:http://graphql.cn/learn/pagination/
#6
姚晓威
评论于 3年前
正在删除评论...
最近在尝试通过 rebing/graphql-laravel 来封装后面的服务,但这货貌似更适合封装数据库ORM操作。
#7
sowork
评论于 3年前
正在删除评论...
看了下只有第一层数据可以使用参数过滤,深层次的数据如何添加过滤参数呢?
#8
sowork
评论于 3年前
回复 #7
正在删除评论...
https://github.com/rebing/graphql-laravel/issues/147
登录后即可添加评论
升级为学院君订阅用户(新年优惠🎁)
内容导航
带参数的查询
嵌套资源
枚举
接口
自定义字段
渴求式加载
基于 jwt-auth 实现接口认证
相关推荐
Laravel API 系列教程(四):基于 GraphQL 构建 Laravel API —— 基本使用篇
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(二) —— 用户列表及详情页
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(三) —— 文章发布及浏览
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 JWT 实现 Laravel API 认证
博客
解决 Laravel JWT 多表认证时获取不到当前认证用户的问题
博客
回到顶部
2022 基于 Laravel 6 构建
关于学院
订阅服务
友情链接
站点地图
本站 CDN 加速服务由又拍云赞助