在现代 Web 开发中,RESTful API 已经成为前后端分离架构的事实标准。无论是面试初级还是高级 PHP 工程师,ThinkPHP 框架下的 RESTful 设计与资源路由实现都是高频考点。本文将从面试官视角出发,系统梳理核心知识点,帮助你从容应对相关提问。
一、什么是 RESTful API?
REST(Representational State Transfer)是一种软件架构风格,强调用统一的接口操作资源。在 RESTful API 中:
- 每个 URL 代表一种资源(Resource)
- 使用 HTTP 动词表示操作类型(GET、POST、PUT、DELETE 等)
- 通过 HTTP 状态码表达请求结果
- 无状态通信,每次请求包含完整信息
例如,对文章资源的典型操作:
| 操作 | HTTP 方法 | URL 示例 | 含义 |
|---|---|---|---|
| 列表 | GET | /api/articles | 获取文章列表 |
| 详情 | GET | /api/articles/1 | 获取 ID 为 1 的文章 |
| 创建 | POST | /api/articles | 新建文章 |
| 更新 | PUT/PATCH | /api/articles/1 | 更新文章 |
| 删除 | DELETE | /api/articles/1 | 删除文章 |
面试中常问:“PUT 和 PATCH 有什么区别?” 标准回答是:PUT 用于全量更新,PATCH 用于部分更新。ThinkPHP 的资源路由默认支持 PUT,若需 PATCH 可手动注册。
二、ThinkPHP 资源路由快速上手
ThinkPHP 5.1 及以上版本内置了资源路由(Resource Route),只需一行代码即可生成标准的 RESTful 路由。
// route/route.php
Route::resource('articles', 'api/Article');
上述代码会自动注册以下路由:
| 请求类型 | 路由规则 | 对应操作 |
|---|---|---|
| GET | articles | index |
| GET | articles/:id | read |
| POST | articles | save |
| PUT | articles/:id | update |
| DELETE | articles/:id | delete |
对应的控制器 app\api\controller\Article 需要实现这些方法:
namespace app\api\controller;
use think\Controller;
use think\Request;
class Article extends Controller
{
public function index()
{
// 返回文章列表
}
public function read($id)
{
// 返回单篇文章
}
public function save(Request $request)
{
// 创建文章
}
public function update(Request $request, $id)
{
// 更新文章
}
public function delete($id)
{
// 删除文章
}
}
面试中可能追问:“资源路由如何只注册部分方法?” 答案是使用 only() 或 except():
Route::resource('articles', 'api/Article')->only(['index', 'read']);
Route::resource('articles', 'api/Article')->except(['delete']);
三、资源路由的进阶配置
1. 嵌套资源路由
当资源存在从属关系时,例如文章下的评论,可使用嵌套:
Route::resource('articles.comments', 'api/Comment');
访问 URL 形如 /articles/1/comments,控制器方法会接收 $article_id 参数。
2. 自定义资源路由
若默认的方法名不符合项目规范,可以自定义:
Route::resource('articles', 'api/Article', [
'index' => 'list',
'read' => 'detail',
'save' => 'create',
'update' => 'modify',
'delete' => 'remove',
]);
3. 伪静态与后缀
为满足 SEO 或客户端需求,可添加 URL 后缀:
Route::resource('articles', 'api/Article')->suffix('html');
此时访问 /articles.html 即可。
四、API 版本控制与路由分组
实际项目中,API 需要版本管理。ThinkPHP 推荐使用路由分组:
Route::group('api/:version', function () {
Route::resource('articles', 'api/:version.Article');
})->pattern(['version' => '\w+']);
这样 URL 变为 /api/v1/articles,控制器位于 app\api\controller\v1\Article。
面试中常问:“如何优雅地处理 API 版本升级?” 回答要点:保持旧版本兼容,新版本独立分组,通过中间件或基类控制器统一响应格式。
五、响应格式与状态码规范
RESTful API 应返回统一的 JSON 结构。ThinkPHP 中可封装基类控制器:
namespace app\api\controller;
use think\Controller;
class Base extends Controller
{
protected function success($data = [], $msg = 'ok', $code = 200)
{
return json([
'code' => $code,
'msg' => $msg,
'data' => $data,
], $code);
}
protected function error($msg = 'error', $code = 400)
{
return json([
'code' => $code,
'msg' => $msg,
'data' => null,
], $code);
}
}
状态码使用建议:
- 200:请求成功
- 201:创建成功
- 204:删除成功且无返回内容
- 400:参数错误
- 401:未认证
- 403:无权限
- 404:资源不存在
- 422:验证失败
- 500:服务器内部错误
面试官可能问:“ThinkPHP 如何统一捕获异常并返回 JSON?” 答案是配置 app.php 中的 exception_handle 或使用 Http 异常类,并在异常处理中判断请求类型是否为 JSON。
六、资源验证与安全
1. 验证器
ThinkPHP 提供验证器,可在控制器中调用:
$validate = validate('Article');
if (!$validate->scene('create')->check($data)) {
return $this->error($validate->getError(), 422);
}
2. 参数过滤
使用 Request 对象的 param()、only() 方法获取指定参数,避免 Mass Assignment 漏洞。
3. 限流与认证
资源路由常配合中间件实现 JWT 认证与接口限流:
Route::resource('articles', 'api/Article')->middleware('auth');
七、常见面试题速答
Q1:资源路由和普通路由的区别?
资源路由自动生成七个 RESTful 动作,减少重复代码,符合 REST 规范;普通路由需手动定义每个规则。
Q2:ThinkPHP 资源路由支持哪些 HTTP 方法?
默认支持 GET、POST、PUT、DELETE,可通过 Route::resource 的第三个参数或额外注册支持 PATCH。
Q3:如何实现 API 的 HATEOAS?
在响应数据中加入 _links 字段,指向相关资源 URL,ThinkPHP 中可在模型或控制器层统一添加。
Q4:资源路由中如何获取 PUT 请求的数据?
ThinkPHP 会自动解析 application/json 或 x-www-form-urlencoded 数据,直接使用 Request::instance()->put() 或 param() 获取。
Q5:如何对资源路由进行缓存?
可使用 Route::resource(...)->cache(60),但需注意缓存粒度与失效策略。
八、总结
掌握 ThinkPHP 的 RESTful API 设计与资源路由实现,不仅是面试加分项,更是日常开发的核心技能。建议从以下维度准备:
- 熟记资源路由的七种动作与 HTTP 方法映射
- 理解嵌套资源、版本分组、自定义方法名的写法
- 能封装统一响应格式与异常处理
- 了解验证器、中间件、限流在 API 中的应用
- 能对比 PUT 与 PATCH、资源路由与普通路由的差异
面试中,除了答出知识点,更要展示你对 REST 架构风格的理解,以及如何用 ThinkPHP 优雅地落地。祝你面试顺利!
未经允许不得转载:任鹏个人博客 » ThinkPHP 面试精讲:RESTful API 设计与资源路由实现

