随着微服务与前后端分离的普及,API网关成为连接前端与后端服务的枢纽。ThinkPHP 8 在保持快速开发的同时,对路由、中间件、注解等进行了全面升级,使其非常适合构建轻量级、高性能的API网关。本文将带领你从零搭建一个具备JWT认证、请求限流、统一响应格式和版本控制的API服务,并将所有代码归纳为一个可直接复用的项目骨架。
一、准备工作与项目初始化
确保本地 PHP 环境 >= 8.0,Composer 已安装。使用 Composer 创建 ThinkPHP 8 项目:
composer create-project topthink/think tp8-api-gateway
cd tp8-api-gateway
项目启动后,调整 .env 文件中的数据库配置(本文以 MySQL 为例)。接下来,我们将逐步构建 API 网关核心模块。
二、路由设计:多版本控制与资源路由
API 需要跟随业务迭代,版本控制必不可少。在 route/app.php 中,我们按版本分组路由,并利用资源路由简化 RESTful 接口定义。
<?php
use thinkfacadeRoute;
// V1 版本路由组
Route::group('v1', function () {
// 用户模块资源路由
Route::resource('users', 'v1.User');
// 其他模块...
})->prefix('v1.')->middleware(appmiddlewareJwtAuth::class);
// V2 版本(示例)
Route::group('v2', function () {
Route::resource('users', 'v2.User');
})->prefix('v2.')->middleware(appmiddlewareJwtAuth::class);
上述代码中,resource 自动生成 index、save、read、update、delete 五个标准方法,同时为整个版本组挂载了 JWT 认证中间件。版本分组通过控制器命名空间 v1.User 区分,方便代码隔离。
三、统一响应格式:让前端处理更简便
为了规范接口返回,我们定义一个响应工具类 app/common/JsonResponse.php。
<?php
namespace appcommon;
class JsonResponse
{
public static function success($data = [], string $msg = '成功', int $code = 200)
{
return json([
'code' => $code,
'msg' => $msg,
'data' => $data
]);
}
public static function error(string $msg = '失败', int $code = 400, $data = [])
{
return json([
'code' => $code,
'msg' => $msg,
'data' => $data
]);
}
}
在控制器中,我们统一调用 JsonResponse::success() 或 JsonResponse::error(),避免返回格式混乱。还可以通过中间件在全局响应后包装,但控制器内显式返回更加灵活。
四、中间件深度应用:JWT认证与限流
API 网关的安全和稳定性离不开中间件。这里实现两个关键中间件:JWT 认证和基于 Redis 的令牌桶限流。
4.1 JWT认证中间件
安装 JWT 扩展:composer require firebase/php-jwt。创建 app/middleware/JwtAuth.php:
<?php
namespace appmiddleware;
use FirebaseJWTJWT;
use FirebaseJWTKey;
use thinkfacadeRequest;
use appcommonJsonResponse;
class JwtAuth
{
public function handle($request, Closure $next)
{
$token = Request::header('Authorization');
if (!$token) {
return JsonResponse::error('缺少Token', 401);
}
try {
$decoded = JWT::decode($token, new Key(config('jwt.secret'), 'HS256'));
// 将用户信息绑定到请求
Request::macro('userInfo', $decoded->data);
} catch (Exception $e) {
return JsonResponse::error('Token无效或过期', 401);
}
return $next($request);
}
}
在 config/jwt.php 中配置密钥,并在中间件注册文件 app/middleware.php 中全局别名注册。
4.2 Redis令牌桶限流中间件
创建 app/middleware/RateLimit.php,基于 Redis 实现简单的滑动窗口限流。
<?php
namespace appmiddleware;
use thinkfacadeCache;
use appcommonJsonResponse;
class RateLimit
{
protected $maxRequests = 100; // 每分钟最大请求数
protected $window = 60; // 窗口秒数
public function handle($request, Closure $next)
{
$key = 'rate_limit:' . request()->ip();
$current = Cache::get($key, 0);
if ($current >= $this->maxRequests) {
return JsonResponse::error('请求过于频繁', 429);
}
Cache::set($key, $current + 1, $this->window);
return $next($request);
}
}
将该中间件挂载到路由组或全局,即可保护网关免受恶意刷量。
五、验证器:确保数据安全
ThinkPHP 8 提供了强大的验证器。新建 app/validate/UserValidator.php:
<?php
namespace appvalidate;
use thinkValidate;
class UserValidator extends Validate
{
protected $rule = [
'name' => 'require|max:50',
'email' => 'require|email|unique:users',
'age' => 'integer|between:1,120',
];
protected $message = [
'name.require' => '姓名必填',
'email.require' => '邮箱必填',
'email.email' => '邮箱格式错误',
'email.unique' => '邮箱已被注册',
'age.integer' => '年龄需为整数',
];
}
在控制器中调用验证:
$data = request()->param();
$validate = new appvalidateUserValidator();
if (!$validate->check($data)) {
return JsonResponse::error($validate->getError());
}
六、实战:用户模块API完整示例
以 V1 用户控制器为例,位于 app/controller/v1/User.php。演示创建用户和显示用户列表:
<?php
namespace appcontrollerv1;
use appcommonJsonResponse;
use appvalidateUserValidator;
use thinkfacadeDb;
class User
{
public function index()
{
$users = Db::name('users')->field('id,name,email')->select();
return JsonResponse::success($users);
}
public function save()
{
$data = request()->param();
$validate = new UserValidator();
if (!$validate->check($data)) {
return JsonResponse::error($validate->getError());
}
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$id = Db::name('users')->insertGetId($data);
return JsonResponse::success(['id' => $id], '创建成功', 201);
}
}
访问 /v1/users 即可获得用户列表,POST /v1/users 创建用户,并自动通过 JWT 中间件校验身份。
七、性能优化与生产建议
1. 开启路由缓存:在 .env 中设置 APP_DEBUG = false,并执行 php think optimize:route。
2. 配置 OpCache:确保 php.ini 中 opcache.enable=1,可大幅提升重复请求速度。
3. 数据库连接池:若高并发场景,推荐使用 Swoole 驱动 + ThinkPHP 的 Swoole 扩展,或前置 MySQL Proxy。
4. 响应压缩:通过 Web 服务器 gzip 压缩 JSON 响应,减少带宽消耗。
八、总结
通过本文的分步实战,我们构建了一个结构清晰、功能完备的 ThinkPHP 8 API 网关。多版本路由保证了平滑升迁,JWT 与限流中间件提供了安全护盾,统一响应和验证器则让接口开发规范而高效。这套骨架可直接应用于中小型项目或微服务入口,在此基础上扩展日志、监控、灰度等功能,即可演变为完整的企业级网关。ThinkPHP 8 的轻量与灵活性,正是快速构建 API 服务的理想选择。

