PHP 怎么编写接口契约

wen PHP项目 2

本文目录导读:

PHP 怎么编写接口契约

  1. 使用 PHP 原生接口(Interface)
  2. 使用 PHPDoc 注解
  3. 使用 OpenAPI/Swagger 定义
  4. 使用 API 响应类
  5. 使用 Request 验证器
  6. 使用 API 响应工具包
  7. 最佳实践建议

在 PHP 中编写接口契约(API Contract),主要有以下几种常用的方法和最佳实践:

使用 PHP 原生接口(Interface)

最基本的接口契约方式:

<?php
// 定义接口契约
interface UserRepositoryInterface
{
    /**
     * 获取用户信息
     * @param int $id 用户ID
     * @return array 用户数据
     */
    public function findUserById(int $id): array;
    /**
     * 保存用户信息
     * @param array $data 用户数据
     * @return bool 保存是否成功
     */
    public function saveUser(array $data): bool;
    /**
     * 删除用户
     * @param int $id 用户ID
     * @return bool 删除是否成功
     */
    public function deleteUser(int $id): bool;
}
// 实现接口
class UserRepository implements UserRepositoryInterface
{
    public function findUserById(int $id): array
    {
        // 实现逻辑
        return ['id' => $id, 'name' => '张三'];
    }
    public function saveUser(array $data): bool
    {
        // 实现逻辑
        return true;
    }
    public function deleteUser(int $id): bool
    {
        // 实现逻辑
        return true;
    }
}

使用 PHPDoc 注解

通过 PHPDoc 注解工具(如 phpDocumentor)来定义更详细的 API 文档:

<?php
/**
 * @apiDefine UserNotFoundError
 * @apiError UserNotFound 用户不存在
 */
/**
 * @api {GET} /api/users/:id 获取用户信息
 * @apiName GetUser
 * @apiGroup User
 * 
 * @apiParam {Number} id 用户ID
 * 
 * @apiSuccess {Number} id 用户ID
 * @apiSuccess {String} name 用户名
 * @apiSuccess {String} email 邮箱
 * @apiSuccess {Date} created_at 创建时间
 * 
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *     {
 *       "id": 1,
 *       "name": "张三",
 *       "email": "zhangsan@example.com",
 *       "created_at": "2024-01-01 12:00:00"
 *     }
 * 
 * @apiError UserNotFound 用户不存在
 * 
 * @apiErrorExample Error-Response:
 *     HTTP/1.1 404 Not Found
 *     {
 *       "error": "UserNotFound",
 *       "message": "用户不存在"
 *     }
 */
class UserController extends Controller
{
    /**
     * 获取用户信息
     * 
     * @param int $id 用户ID
     * @return JsonResponse
     */
    public function show(int $id): JsonResponse
    {
        try {
            $user = User::findOrFail($id);
            return response()->json($user);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'error' => 'UserNotFound',
                'message' => '用户不存在'
            ], 404);
        }
    }
}

使用 OpenAPI/Swagger 定义

这是最标准的 API 契约方式,可以自动生成文档:

# api.yaml
openapi: 3.0.0
info: User API
  version: 1.0.0
  description: 用户管理API
paths:
  /users/{id}:
    get:
      summary: 获取用户信息
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: 用户不存在
components:
  schemas:
    User:
      type: object
      required:
        - id
        - name
        - email
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        email:
          type: string
        created_at:
          type: string
          format: date-time

PHP 中使用 Swagger 注解:

<?php
use OpenApi\Annotations as OA;
/**
 * @OA\Get(
 *     path="/api/users/{id}",
 *     @OA\Parameter(
 *         name="id",
 *         in="path",
 *         required=true,
 *         @OA\Schema(type="integer")
 *     ),
 *     @OA\Response(
 *         response="200",
 *         description="成功",
 *         @OA\JsonContent(ref="#/components/schemas/User")
 *     )
 * )
 */
class UserController extends Controller
{
    public function show($id)
    {
        // 实现逻辑
    }
}

使用 API 响应类

创建统一的响应格式:

<?php
class ApiResponse
{
    /**
     * 成功响应
     */
    public static function success($data = null, string $message = 'success', int $code = 200): JsonResponse
    {
        return response()->json([
            'code' => $code,
            'message' => $message,
            'data' => $data
        ], $code);
    }
    /**
     * 错误响应
     */
    public static function error(string $message, int $code = 400, $data = null): JsonResponse
    {
        return response()->json([
            'code' => $code,
            'message' => $message,
            'data' => $data
        ], $code);
    }
    /**
     * 分页响应
     */
    public static function paginate($items, int $total, int $page, int $perPage): JsonResponse
    {
        return response()->json([
            'code' => 200,
            'message' => 'success',
            'data' => [
                'items' => $items,
                'pagination' => [
                    'total' => $total,
                    'page' => $page,
                    'per_page' => $perPage
                ]
            ]
        ]);
    }
}
// 使用示例
class UserController extends Controller
{
    public function index()
    {
        $users = User::paginate(10);
        return ApiResponse::success($users);
    }
    public function store(Request $request)
    {
        try {
            $user = User::create($request->validated());
            return ApiResponse::success($user, '创建成功', 201);
        } catch (Exception $e) {
            return ApiResponse::error('创建失败', 400);
        }
    }
}

使用 Request 验证器

定义输入验证规则:

<?php
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
    /**
     * 验证规则
     */
    public function rules()
    {
        return [
            'name' => 'required|string|max:100',
            'email' => 'required|email|unique:users',
            'password' => 'required|confirmed|min:8',
            'phone' => 'nullable|regex:/^1[3-9]\d{9}$/'
        ];
    }
    /**
     * 自定义错误消息
     */
    public function messages()
    {
        return [
            'name.required' => '用户名不能为空',
            'email.email' => '邮箱格式不正确',
            'password.min' => '密码至少8位'
        ];
    }
}
// 在控制器中使用
class UserController extends Controller
{
    public function store(StoreUserRequest $request)
    {
        // 验证通过后才执行到这里
        $validated = $request->validated();
        $user = User::create($validated);
        return ApiResponse::success($user, '创建成功', 201);
    }
}

使用 API 响应工具包

推荐使用流行的工具包:

# 安装 Laravel 的 API 响应工具包
composer require spatie/laravel-fractal
# 或使用 DTO(数据传输对象)
composer require spatie/data-transfer-object
<?php
use Spatie\DataTransferObject\DataTransferObject;
class UserDTO extends DataTransferObject
{
    public int $id;
    public string $name;
    public string $email;
    public ?string $phone;
    public DateTime $created_at;
    // 定义验证规则
    protected function validationRules(): array
    {
        return [
            'name' => 'required|string',
            'email' => 'required|email'
        ];
    }
}
// 使用
$userDTO = new UserDTO([
    'id' => 1,
    'name' => '张三',
    'email' => 'zhangsan@example.com',
    'phone' => null,
    'created_at' => new DateTime()
]);

最佳实践建议

  1. 定义清晰的命名规范

    • 接口类以 Interface
    • 实现类使用具体名字
  2. 统一响应格式

    • 使用一致的 JSON 结构
    • 定义状态码规范
  3. 版本化你的 API

    Route::prefix('api/v1')->group(function () {
        Route::resource('users', 'UserController');
    });
  4. 使用异常处理

    try {
        // 业务逻辑
    } catch (\Exception $e) {
        Log::error($e->getMessage());
        return ApiResponse::error('服务器内部错误', 500);
    }
  5. 编写单元测试

    public function test_get_user_success()
    {
        $response = $this->get('/api/users/1');
        $response->assertStatus(200)
                 ->assertJsonStructure([
                     'code', 'message', 'data' => [
                         'id', 'name', 'email'
                     ]
                 ]);
    }

通过这些方式,你可以建立清晰、可维护的 API 接口契约,方便前后端开发和文档生成。

抱歉,评论功能暂时关闭!