一、API设计原则与规范
在开始开发前,我们需要遵循RESTful API设计规范:
- 使用HTTP动词(GET, POST, PUT, DELETE)表示操作类型
- 资源使用名词复数形式(如 /api/v1/products)
- API版本控制(/api/v1/…)
- 统一响应格式(JSON)
- 合理的HTTP状态码(200, 201, 400, 401, 404, 500等)
二、项目初始化与配置
创建ThinkPHP项目并配置API专用环境:
composer create-project topthink/think tp-api cd tp-api
配置API路由(route/app.php):
use thinkfacadeRoute; // API版本分组 Route::group('api', function() { // V1版本API Route::group('v1', function() { // 产品资源路由 Route::resource('products', 'v1.Product'); // 用户认证路由 Route::post('login', 'v1.Auth/login'); Route::post('register', 'v1.Auth/register'); }); });
三、构建产品API模块
1. 创建产品模型
// app/model/Product.php namespace appmodel; use thinkModel; class Product extends Model { // 设置表名 protected $name = 'products'; // 自动写入时间戳 protected $autoWriteTimestamp = true; // 字段类型转换 protected $type = [ 'price' => 'float', 'stock' => 'integer', 'is_on_sale' => 'boolean' ]; // 搜索器 - 按名称搜索 public function searchNameAttr($query, $value) { $query->where('name', 'like', '%' . $value . '%'); } }
2. 创建API控制器
// app/controller/v1/Product.php namespace appcontrollerv1; use appmodelProduct; use thinkfacadeRequest; use thinkResponse; class Product { /** * 获取产品列表 * GET /api/v1/products */ public function index() { // 获取分页参数 $page = Request::param('page/d', 1); $size = Request::param('size/d', 10); // 获取搜索参数 $search = Request::param('search/s', ''); // 构建查询 $query = Product::withSearch(['name'], ['name' => $search]); // 分页查询 $products = $query->paginate([ 'page' => $page, 'list_rows' => $size ]); // 返回JSON响应 return Response::create([ 'code' => 200, 'message' => 'success', 'data' => [ 'list' => $products->items(), 'total' => $products->total(), 'current_page' => $products->currentPage(), 'last_page' => $products->lastPage() ] ], 'json'); } /** * 创建新产品 * POST /api/v1/products */ public function save() { // 获取请求数据 $data = Request::only([ 'name', 'description', 'price', 'stock', 'is_on_sale' ]); // 数据验证 $validate = new thinkValidate([ 'name|产品名称' => 'require|min:2', 'price|价格' => 'require|float|gt:0', 'stock|库存' => 'require|integer|egt:0', ]); if (!$validate->check($data)) { return Response::create([ 'code' => 400, 'message' => $validate->getError() ], 'json', 400); } // 创建产品 $product = Product::create($data); if ($product) { return Response::create([ 'code' => 201, 'message' => '产品创建成功', 'data' => $product ], 'json', 201); } return Response::create([ 'code' => 500, 'message' => '产品创建失败' ], 'json', 500); } // 其他方法:read, update, delete... }
四、实现JWT用户认证
1. 安装JWT扩展
composer require firebase/php-jwt
2. 创建认证服务
// app/service/JwtAuth.php namespace appservice; use FirebaseJWTJWT; use FirebaseJWTKey; class JwtAuth { // 密钥 private static $secret = 'your_secret_key'; // 创建Token public static function createToken($userId) { $payload = [ 'iss' => 'tp-api', // 签发者 'iat' => time(), // 签发时间 'exp' => time() + 7200, // 过期时间(2小时) 'sub' => $userId // 用户ID ]; return JWT::encode($payload, self::$secret, 'HS256'); } // 验证Token public static function verifyToken($token) { try { $decoded = JWT::decode($token, new Key(self::$secret, 'HS256')); return (array)$decoded; } catch (Exception $e) { return false; } } }
3. 创建认证中间件
// app/middleware/JwtAuth.php namespace appmiddleware; use appserviceJwtAuth; use thinkfacadeRequest; class JwtAuth { public function handle($request, Closure $next) { // 获取Token $token = Request::header('Authorization'); if (!$token) { return json([ 'code' => 401, 'message' => '缺少认证Token' ], 401); } // 验证Token $authInfo = JwtAuth::verifyToken(str_replace('Bearer ', '', $token)); if (!$authInfo) { return json([ 'code' => 401, 'message' => '无效或过期的Token' ], 401); } // 将用户ID保存到请求对象 $request->userId = $authInfo['sub']; return $next($request); } }
五、API速率限制与安全防护
1. 实现API速率限制
// app/middleware/RateLimit.php namespace appmiddleware; use thinkfacadeCache; class RateLimit { public function handle($request, Closure $next) { $ip = $request->ip(); $key = 'api_rate_limit:' . $ip; // 每分钟限制60次请求 $limit = 60; $expire = 60; // 60秒 $count = Cache::get($key, 0); if ($count >= $limit) { return json([ 'code' => 429, 'message' => '请求过于频繁,请稍后再试' ], 429); } // 增加计数 Cache::set($key, $count + 1, $expire); return $next($request); } }
2. 配置全局中间件
// app/middleware.php return [ // 全局中间件 appmiddlewareRateLimit::class, // API分组中间件 'api' => [ appmiddlewareJwtAuth::class ] ];
六、API文档生成
使用ThinkPHP的注解功能生成API文档:
// 在控制器方法中添加注解 /** * @title 获取产品列表 * @url GET /api/v1/products * @param string name:page type:int desc:页码 default:1 * @param string name:size type:int desc:每页数量 default:10 * @param string name:search type:string desc:搜索关键词 * @return {"code":200,"message":"success","data":{"list":[],"total":0}} */ public function index() { // ... }
使用扩展包自动生成文档:
composer require topthink/think-apidoc
七、API测试与调试
1. 使用Postman测试API
示例请求:
GET /api/v1/products?page=1&size=5&search=手机 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
2. 测试响应示例
{ "code": 200, "message": "success", "data": { "list": [ { "id": 1, "name": "智能手机", "price": 3999.00, "stock": 100, "is_on_sale": true }, // ...其他产品 ], "total": 15, "current_page": 1, "last_page": 3 } }
八、性能优化策略
- 数据库优化:合理使用索引,避免N+1查询
- 缓存机制:使用Redis缓存频繁访问的数据
- 响应压缩:启用Gzip压缩减少传输大小
- 延迟加载:按需加载关联数据
- 队列处理:耗时操作异步处理
缓存优化示例
// 使用缓存优化产品详情查询 public function read($id) { $cacheKey = 'product:' . $id; $product = cache($cacheKey); if (!$product) { $product = Product::find($id); if ($product) { cache($cacheKey, $product, 3600); // 缓存1小时 } } // ... }
九、项目结构总结
最终项目结构如下:
tp-api/ ├─ app/ │ ├─ controller/ │ │ ├─ v1/ │ │ │ ├─ Product.php │ │ │ ├─ Auth.php │ ├─ model/ │ │ ├─ Product.php │ │ ├─ User.php │ ├─ middleware/ │ │ ├─ JwtAuth.php │ │ ├─ RateLimit.php │ ├─ service/ │ │ ├─ JwtAuth.php ├─ config/ │ ├─ cache.php │ ├─ middleware.php │ ├─ route.php ├─ database/ │ ├─ migrations/ │ │ ├─ create_products_table.php ├─ route/ │ ├─ app.php
十、API开发最佳实践
- 遵循RESTful设计规范
- 使用版本控制(v1, v2)
- 统一的错误处理机制
- 合理的HTTP状态码
- 数据验证与过滤
- 接口文档自动化
- 全面的单元测试
- API监控与日志