如何从Laravel后端生成TypeScript类型?实践困惑求解
问题:Laravel API返回消息在OpenAPI文档中的复用方案
我正在研究如何从Laravel应用的API生成TypeScript类型,目前用Scribe生成API文档,再基于该文档生成TypeScript类型。但遇到一个问题:服务器返回的消息需要包含在OpenAPI文档中,按当前方案,每个端点都必须使用专属Resource并手动放入服务器消息,否则API文档无法包含该消息。
示例代码如下:
控制器方法
/** * @apiResource App\Http\Admin\Resources\PermissionCreateResource * @apiResourceModel App\Models\Permission * @param PermissionCreateRequest $request */ public function create(PermissionCreateRequest $request): JsonResponse { $input = $request->validated(); $permission = $this->permissionFactory->createPermission($input); return new JsonResponse(new PermissionCreateResource($permission), Response::HTTP_CREATED); }
对应的PermissionCreateResource
public function toArray(Request $request): array { return [ 'message' => 'Permission created', 'data' => [ 'id' => $this->id, 'name' => $this->name, ] ]; }
解决方案
方案1:封装通用基础Resource类
创建一个基础Resource类,统一处理message和data的结构,其他业务Resource继承该类,避免重复编写消息结构,同时让Scribe能识别统一的响应格式。
// app/Http/Resources/BaseResource.php class BaseResource extends JsonResource { protected string $message; public function __construct($resource, string $message) { parent::__construct($resource); $this->message = $message; } public function toArray(Request $request): array { return [ 'message' => $this->message, 'data' => parent::toArray($request), ]; } }
业务Resource继承后只需定义data字段:
// app/Http/Admin/Resources/PermissionCreateResource.php class PermissionCreateResource extends BaseResource { public function toArray(Request $request): array { return parent::toArray($request) + [ 'data' => [ 'id' => $this->id, 'name' => $this->name, ] ]; } }
控制器调用时传入消息:
return new JsonResponse(new PermissionCreateResource($permission, 'Permission created'), Response::HTTP_CREATED);
方案2:用Scribe的@apiResponse注解定义通用结构
如果不想修改Resource层级,可以直接在控制器注释中用@apiResponse手动声明包含message的响应格式,复用通用Resource即可。
/** * @apiResourceModel App\Models\Permission * @apiResponse { * "message": "string", * "data": { * "id": "integer", * "name": "string" * } * } 201 "Permission created" * @param PermissionCreateRequest $request */ public function create(PermissionCreateRequest $request): JsonResponse { $input = $request->validated(); $permission = $this->permissionFactory->createPermission($input); return response()->json([ 'message' => 'Permission created', 'data' => new PermissionResource($permission) ], Response::HTTP_CREATED); }
方案3:Laravel响应宏统一返回格式
在AppServiceProvider中定义响应宏,让所有API返回遵循统一格式,再配置Scribe识别该结构。
// app/Providers/AppServiceProvider.php use Illuminate\Support\Facades\Response; public function boot() { Response::macro('apiSuccess', function ($data, string $message = '操作成功', int $statusCode = 200) { return response()->json([ 'message' => $message, 'data' => $data, ], $statusCode); }); }
控制器中使用:
return response()->apiSuccess(new PermissionResource($permission), 'Permission created', Response::HTTP_CREATED);
之后可以通过Scribe的@apiResponse注解或自定义解析器,让OpenAPI文档自动包含message字段的定义。
内容的提问来源于stack exchange,提问作者Maarduk
相关产品推荐
相关产品推荐

