--- name: backend-route description: Generate route configuration for madong module. Supports both app (main project) and plugin targets. Creates route.php files for adminapi and api with proper OpenAPI scan paths. --- # Generate Route Create route configuration files for modules. ## File Location **App (主项目):** ``` app/adminapi/config/route.php app/api/config/route.php ``` **Plugin (插件):** ``` plugin/{plugin}/config/route.php ``` ## AdminAPI Route Template ```php registerRoute([ 'route_prefix' => '/openapi', 'register_route' => true, 'openapi_doc' => [ 'scan_path' => [ base_path('app/schema'), // 基础schema base_path('app/adminapi'), base_path('app/install'), ], 'modify' => function (OA\OpenApi $openapi) { $openapi->info->title = config('app.name') . ' API'; $openapi->info->version = '1.0.0'; $openapi->servers = [ new OA\Server([ 'url' => '/adminapi', 'description' => request()->host(), ]), ]; if (!$openapi->components instanceof OA\Components) { $openapi->components = new OA\Components([]); } $openapi->components->securitySchemes = [ new OA\SecurityScheme([ 'securityScheme' => 'api_key', 'type' => 'apiKey', 'name' => config('madong.jwt.app.token_name', 'Authorization'), 'in' => 'header', ]), ]; }, ], ]); }); ``` ## API Route Template ```php registerRoute([ 'route_prefix' => '/openapi', 'register_route' => true, 'openapi_doc' => [ 'scan_path' => [ base_path('app/api'), ], 'modify' => function (OA\OpenApi $openapi) { $openapi->info->title = config('app.name') . ' API'; $openapi->info->version = '1.0.0'; $openapi->servers = [ new OA\Server([ 'url' => '/api', 'description' => request()->host(), ]), ]; if (!$openapi->components instanceof OA\Components) { $openapi->components = new OA\Components([]); } $openapi->components->securitySchemes = [ new OA\SecurityScheme([ 'securityScheme' => 'api_key', 'type' => 'apiKey', 'name' => config('core.jwt.app.token_name', 'Authorization'), 'in' => 'header', ]), ]; }, ], ]); }); ``` ## Plugin Route Template ```php registerRoute([ 'route_prefix' => '/openapi', 'register_route' => true, 'openapi_doc' => [ 'scan_path' => [ // 插件的 adminapi 目录 __DIR__ . '/app/adminapi', // 插件的 api 目录 __DIR__ . '/app/api', ], 'modify' => function (OA\OpenApi $openapi) { $openapi->info->title = '{Plugin} API'; $openapi->info->version = '1.0.0'; $openapi->servers = [ new OA\Server([ 'url' => '/{plugin_path}', 'description' => request()->host(), ]), ]; if (!$openapi->components instanceof OA\Components) { $openapi->components = new OA\Components([]); } $openapi->components->securitySchemes = [ new OA\SecurityScheme([ 'securityScheme' => 'api_key', 'type' => 'apiKey', 'name' => config('madong.jwt.app.token_name', 'Authorization'), 'in' => 'header', ]), ]; }, ], ]); }); ``` ## Route Auto-Discovery Controllers are auto-loaded by webman based on naming convention: | Controller | Auto Route | |------------|------------| | `adminapi/controller/member/MemberController.php` | `/adminapi/member/member` | | `adminapi/controller/member/UserController.php` | `/adminapi/member/user` | | `api/controller/auth/AuthController.php` | `/api/auth/auth` | ### Route Naming Convention ``` app/adminapi/controller/{module}/{Model}Controller.php ↓ /{module}/{model} ``` ## Swagger Scan Path Configuration ### AdminAPI OpenAPI Scan ```php 'scan_path' => [ base_path('app/schema'), // Schema DTOs base_path('app/adminapi'), // AdminAPI controllers, validates base_path('app/install'), // Install controllers ], ``` ### API OpenAPI Scan ```php 'scan_path' => [ base_path('app/api'), // API controllers ], ``` ## Custom OpenAPI JSON Endpoint When the project requires the Swagger UI to load `/openapi.json` instead of the package default `/openapi/doc`, do not modify `vendor/webman-tech/swagger`. Use `app\controller\OpenApiController` to render the Swagger UI and generate the JSON document with `ConfigOpenapiDocDTO` and `WebmanTech\Swagger\Overwrite\Generator`. In each API route group: ```php $openApiController = new OpenApiController(); Route::get('/openapi', static fn () => $openApiController->index('/api/openapi.json')); Route::get('/openapi.json', static fn () => $openApiController->document($openapiDocConfig)); $config = ConfigOpenapiDocDTO::fromConfig($openapiDocConfig); RouteRegister::create()->register((new Reader())->getData($config->getScanSources())); ``` For Admin API, use `/adminapi/openapi.json` as the Swagger UI document URL. Keep the existing scan paths and OpenAPI `modify` callback in `$openapiDocConfig` so generated documentation and annotation route registration remain consistent. ### Plugin OpenAPI Scan 当前项目插件路由以 `plugin/{plugin}/config/route.php` 为入口,按访问端分成独立路由组。已验证的 `produce` 插件使用以下分组: - `/api`:前台 Web 接口,扫描 `base_path('plugin/{plugin}/app/api')`。 - `/appapi`:移动端/业务端 APP 接口,扫描 `base_path('plugin/{plugin}/app/appapi')`。 - `/adminapi`:管理端接口,扫描 `base_path('plugin/{plugin}/app/adminapi')`。 为插件新增业务端接口时,不要把 APP 控制器放进 `app/api`;应放入 `plugin/{plugin}/app/appapi/controller`,并在插件路由中新增或确认 `/appapi` 分组扫描该目录。OpenAPI `servers.url` 对应设置为 `/appapi`。 ```php 'scan_path' => [ base_path('plugin/{plugin}/app/appapi'), ], ``` ## Auto-generation Checklist When generating route: - [ ] Create adminapi/config/route.php with Swagger - [ ] Create api/config/route.php with Swagger - [ ] Configure scan_path to include all relevant directories - [ ] Set correct security scheme (Authorization header) - [ ] Configure server URL and description - [ ] For plugins, use __DIR__ for relative paths