dingo/api

dingo/api 是一个 Lumen 和 Laravel 都可用的 RestFul 工具包,帮助我们快速的开始构建 RestFul Api。

1
2
composer require dingo/api
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

注意点:

由于路由被 DingoApi 接管了,如果将来部署上线后你需要缓存路由,可以使用 php artisan api:cache 代替 php artisan route:cache ,本地测试请不要执行这个命令。

路由交给 DingoApi 来处理了,所以模型绑定的中间件并没有注册上。需要手动增加 bindings 中间件。【否则会导致隐形路由模型绑定功能失效】

使用 Accept 头来指定我们需要访问的 API 版本

Accept: application/<API_STANDARDS_TREE>.<API_SUBTYPE>.v1+json

API_STANDARDS_TREE 有是三个值可选

  • x 本地开发的或私有环境的
  • prs 未对外发布的,提供给公司 app,单页应用,桌面应用等
  • vnd 对外发布的,开放给所有用户

是否有 N+1 问题呢?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dingo api V2.2.3: 该版本的查询是会存在 N+1 问题的,因为目前 Dingo 最新的版本引入了一个 Bug ——
https://github.com/dingo/api/issues/1645 ,有兴趣的同学可以关注一下这个 Bug,在这个 Bug 修复之前,我们 include 如果太深了,则会出现 N+1 问题,因为我们使用 topic.user 这样的深层嵌套。

解决方法有这么几个:

- 持续关注这个 Bug,等待 Bug 解决;
- 安装回 Dingo 2.0.0 以下的版本;
- 关闭 Dingo 的预加载,手动处理预加载的问题。

这里可以暂时使用第三种:先来关闭 Dingo 的预加载。
app(\Dingo\Api\Transformer\Factory::class)->disableEagerLoading();

socialiteproviders

由于 Laravel 本身自带的 socialite 不包含微信、qq等第三方登录驱动,故 socialiteproviders 提供了更多的第三方登录方式,基本上你需要的,都能在这里找到。socialiteproviders算是对 socialite 的补充。

1
2
3
4
5
# 微信
composer require socialiteproviders/weixin

# qq
composer require socialiteproviders/qq

jwt

JWT 超详细分析

JWT 在项目中的实际使用

使用 Jwt-Auth 实现 API 用户认证以及无痛刷新访问令牌

JWT-Auth 黑名单功能

Token 的种类,一般来说 token 主要三种:

  • 自定义的 token:开发者根据业务逻辑自定义的 token
  • JWT:JSON Web Token,定义在 RFC 7519 中的一种 token 规范
  • Oauth2.0:定义在 RFC 6750 中的一种授权规范,但这其实并不是一种 token,只是其中也有用到 token

Oauth2.0 && JWT:两者其实并不是一个层面的东西。Oauth2.0 是一个方便的第三方授权规范,而 JWT 是一个 token 结构规范。

JWT 是 JSON Web Token 的缩写,是一个非常轻巧的规范,这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。

JWT 由头部(header)、载荷(payload)与签名(signature)组成。

用户登录后生成的 token 不需要保存在数据库,直接根据前端传递过来的 token 判断用户的登录状态。

JWT 生成的 Token 包含 token 生效时间和一个签名,利用签名可以验证数据是否被篡改,然后再获取 token 里携带的生效时间判断 token 是否有效。

刷新 Token 就是将旧 Token 放入黑名单,然后生成一个新的 Token。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
composer require tymon/jwt-auth:1.0.0-rc.4.1

JWT 生成 token 的四个优点
- 防 CSRF
- 适合移动应用
- 无状态
- 编码数据
> 前两个是 token 的优势,后两个是 JWT 独特的优势。

JWT 前后端 token 过期时的交互流程:
1. 用户请求一个业务接口时,如果后端发现 token 失效了,就返回 token 失效的信息,
2. 前端界面提示网络有问题、稍后重试等提示,并调用续签 token 接口
3. 用户再发起一次业务请求时,前端直接携带新的 token 去请求服务器

Fractal

api 输出结果处理层,也可以选择官方的 eloquent-resources

  • Fractal 是一个转换层(transformer),API 开发中非常方便的一种开发方法,可以帮助我们处理响应数据的结构与复杂的嵌套关系,最后将数据返回给客户端。可以把 Fractal 理解为 Web 开发中视图,控制着 API 的最终数据输出。Laravel 5.5 的新功能 eloquent-resources 整体思路跟 Fractal 一致,用法也基本相同。

  • Fractal 为我们提供了 3 种 基本结构。

    DataArraySerializer 结构类似 eloquent-resources 的 Data Wrapping

    ArraySerializer 结构类似 eloquent-resources 的 withoutWrapping

    JsonApiSerializer 结构出自 JSON-API,是一套 json 接口响应规范。

    我们常用的结构是 DataArraySerializer 和 ArraySerializer

  • DingoApi 已经安装了 Fractal,并且做了很多整合,基本解决了 N+1 问题,我们可以快速的开始使用。但是它返回的单资源的数据结构为 DataArraySerializer,我们可以使用以下扩展包将 dingo/api 的单资源数据结构更改为 ArraySerializer,减少嵌套层数。

    1
    
    composer require liyu/dingo-serializer-switch
    
  • 用法

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    # 返回单个资源
    return $this->response->item($topics, new TopicTransformer())->setStatusCode(201);
    
    # 返回多个资源
    $this->response->collection(Topics::all(), new TopicTransformer());
    
    # 返回列表分页数据
    $this->response->paginator($topics, new TopicTransformer());
    
    # 返回空数据
    $this->response->noContent();
    

laravel-query-logger

查询日志扩展

1
2
3
4
composer require overtrue/laravel-query-logger --dev

# 日志路径
cd ./storage/logs

barryvdh/laravel-cors

解决跨域问题

encore/laravel-admin

后台管理系统

app/Http/Kernel.php

需要注释掉中间件:ConvertEmptyStringsToNull::class,否则选填字段为空且字段设置为 not null 时,会报错:Column 'xxx' cannot be null

guzzlehttp/guzzle

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.

opis/closure

用于闭包序列化和反序列化

Opis Closure is a library that aims to overcome PHP’s limitations regarding closure serialization by providing a wrapper that will make all closures serializable.

作用:使用 Opis Closure 可以自动补全闭包中用到的类名、函数名、常量的完整路径。当然还有更多功能,详情请看官网。

eg: 闭包中使用了 CustomerRepo::setCache("key", 11); 会自动转为 \App\Facades\CustomerRepo::setCache("key", 11);

barryvdh/laravel-ide-helper

Laravel 超好用的代码提示工