注解路由

XinAdmin 采用了类似 Spring Boot 风格的注解路由系统 (AnnoRoute),这种设计使得路由定义更加直观和便捷。注解路由系统基于 PHP 8 的 Attributes 特性实现,提供了丰富的注解来定义 API 接口。

TIP

XinAdmin 的注解路由系统允许开发者通过 #[RequestMapping]#[GetMapping]#[PostMapping] 等注解快速定义 API 接口,大大提高了开发效率。

系统特点

  • 声明式路由: 通过注解直接在代码中声明路由,无需额外的路由配置文件
  • 层级化设计: 支持类级别和方法级别的路由注解
  • 权限集成: 路由定义与权限系统紧密结合
  • 中间件支持: 支持在类和方法级别配置中间件
  • 灵活约束: 支持路由参数正则约束
TIP

注解路由系统大大简化了路由定义过程,使代码更易于维护和理解。

RequestMapping 类注解

#[RequestMapping] 是类级别的注解,用于定义控制器的基本路由配置。它是注解路由系统的核心组件之一。

属性说明

  • routePrefix (string): 路由前缀,定义该控制器的基础路由路径
  • abilitiesPrefix (string): 权限前缀,定义该控制器的权限前缀
  • middleware (string | array): 中间件配置,可以是单个中间件字符串或中间件数组
  • authGuard (?string): 用户提供程序,指定使用的认证守卫
<?php

namespace App\Http\Controllers\Sys;

use App\Http\Controllers\BaseController;
use App\Providers\AnnoRoute\Attribute\RequestMapping;

#[RequestMapping('/sys/users', 'system.user', middleware: ['auth:sanctum'])]
class SysUserController extends BaseController
{
    // 控制器逻辑
}

在这个例子中:

  • 路由前缀为 /sys/users
  • 权限前缀为 system.user
  • 应用 auth:sanctum 中间件
INFO

#[RequestMapping] 注解只能应用于类,用于定义控制器的基本配置。

方法级注解

方法级注解用于定义具体的操作接口,包括 #[GetMapping]#[PostMapping]#[PutMapping]#[DeleteMapping],它们分别对应不同的 HTTP 请求方法。

GetMapping

#[GetMapping] 用于定义 GET 请求的路由,适用于查询操作。

  • route (string): 路由路径,与类上的 routePrefix 拼接形成完整路由

  • authorize (string): 权限字符串,与类上的 abilitiesPrefix 拼接形成完整权限

  • middleware (string | array): 路由中间件配置

  • where (array): 路由参数约束

#[RequestMapping('/sys/users', 'system.user')]
class SysUserController extends BaseController
{
    #[GetMapping('/list', 'list')]
    public function list(): JsonResponse
    {
        return $this->success($this->repository()->paginate());
    }
}

在这个例子中,最终生成的路由是 GET /sys/users/list,权限是 system.user.list

PostMapping

#[PostMapping] 用于定义 POST 请求的路由,通常用于创建操作。

#[PostMapping('/create', 'create')]
public function create(): JsonResponse
{
    $data = $this->validateData();
    $result = $this->repository()->create($data);
    return $this->success($result);
}

PutMapping

#[PutMapping] 用于定义 PUT 请求的路由,通常用于更新操作。

#[PutMapping('/update/{id}', 'update')]
public function update(int $id): JsonResponse
{
    $data = $this->validateData();
    $result = $this->repository()->update($id, $data);
    return $this->success($result);
}

DeleteMapping

#[DeleteMapping] 用于定义 DELETE 请求的路由,用于删除操作。

#[DeleteMapping('/delete/{id}', 'delete')]
public function delete(int $id): JsonResponse
{
    $result = $this->repository()->delete($id);
    return $this->success(['deleted' => $result]);
}
TIP

方法级注解会继承类级注解的配置,如路由前缀、权限前缀等,这样可以避免重复配置。

CRUD 快捷注解

XinAdmin 提供了便捷的 CRUD 快捷注解,可以快速生成标准的增删改查接口,减少重复代码的编写。

Create 注解

#[Create] 注解用于快速生成创建接口,自动处理创建逻辑。

#[RequestMapping('/sys/users', 'system.user')]
#[Create]
class SysUserController extends BaseController
{
    // 使用 #[Create] 注解后,会自动生成创建接口
    // 对应路由: POST /sys/users/create
    // 权限: system.user.create
}

Query 注解

#[Query] 注解用于快速生成查询接口,包括列表查询和分页功能。

#[RequestMapping('/sys/users', 'system.user')]
#[Query]
class SysUserController extends BaseController
{
    // 使用 #[Query] 注解后,会自动生成查询接口
    // 对应路由: GET /sys/users/list
    // 权限: system.user.list
}

Find 注解

#[Find] 注解用于快速生成查找单条记录的接口。

#[RequestMapping('/sys/users', 'system.user')]
#[Find]
class SysUserController extends BaseController
{
    // 使用 #[Find] 注解后,会自动生成查找接口
    // 对应路由: GET /sys/users/find/{id}
    // 权限: system.user.find
}

Update 注解

#[Update] 注解用于快速生成更新接口。

#[RequestMapping('/sys/users', 'system.user')]
#[Update]
class SysUserController extends BaseController
{
    // 使用 #[Update] 注解后,会自动生成更新接口
    // 对应路由: PUT /sys/users/update/{id}
    // 权限: system.user.update
}

Delete 注解

#[Delete] 注解用于快速生成删除接口。

#[RequestMapping('/sys/users', 'system.user')]
#[Delete]
class SysUserController extends BaseController
{
    // 使用 #[Delete] 注解后,会自动生成删除接口
    // 对应路由: DELETE /sys/users/delete/{id}
    // 权限: system.user.delete
}

组合使用

这些注解可以组合使用,快速生成完整的 CRUD 接口:

#[RequestMapping('/sys/users', 'system.user')]
#[Query, Create, Update, Delete]
class SysUserController extends BaseController
{
    // 自动生成完整的 CRUD 接口
    // GET /sys/users/list
    // POST /sys/users/create
    // PUT /sys/users/update/{id}
    // DELETE /sys/users/delete/{id}
}
INFO

CRUD 快捷注解依赖于 Repository 模式,需要在控制器中实现 repository() 方法返回对应的仓库实例。

使用示例

下面是一个完整的控制器示例,展示了如何使用注解路由系统:

<?php

namespace App\Http\Controllers\Sys;

use App\Http\Controllers\BaseController;
use App\Providers\AnnoRoute\Attribute\Create;
use App\Providers\AnnoRoute\Attribute\Delete;
use App\Providers\AnnoRoute\Attribute\GetMapping;
use App\Providers\AnnoRoute\Attribute\PostMapping;
use App\Providers\AnnoRoute\Attribute\PutMapping;
use App\Providers\AnnoRoute\Attribute\Query;
use App\Providers\AnnoRoute\Attribute\RequestMapping;
use App\Providers\AnnoRoute\Attribute\Update;
use App\Repositories\RepositoryInterface;
use App\Repositories\Sys\SysUserController;
use Illuminate\Http\JsonResponse;

/**
 * 用户管理
 */
#[RequestMapping('/sys/users', 'system.user', middleware: ['auth:sanctum'])]
#[Query, Create, Update, Delete]
class SysUserController extends BaseController
{
    // 配置无需权限验证的方法
    protected array $noPermission = ['profile', 'updateProfile'];

    /**
     * 注入数据仓库
     */
    protected function repository(): RepositoryInterface
    {
        return app(\App\Repositories\Sys\SysUserRepository::class);
    }

    /**
     * 获取用户资料
     */
    #[GetMapping('/profile', 'profile')]
    public function profile(): JsonResponse
    {
        $user = auth()->user();
        return $this->success($user);
    }

    /**
     * 更新用户资料
     */
    #[PutMapping('/profile', 'updateProfile')]
    public function updateProfile(): JsonResponse
    {
        $data = $this->validateData();
        $user = auth()->user();
        $user->update($data);
        return $this->success($user);
    }

    /**
     * 重置密码
     */
    #[PutMapping('/reset-password/{id}', 'resetPassword')]
    public function resetPassword(int $id): JsonResponse
    {
        $data = $this->validateData([
            'password' => 'required|string|min:6',
            'confirm_password' => 'required|same:password',
        ]);
        
        $user = $this->repository()->find($id);
        $user->password = bcrypt($data['password']);
        $user->save();
        
        return $this->success(['message' => '密码重置成功']);
    }
}

在这个示例中:

  1. 使用 #[RequestMapping] 定义了路由前缀 /sys/users 和权限前缀 system.user
  2. 使用 #[Query, Create, Update, Delete] 生成标准的 CRUD 接口
  3. 通过 $noPermission 配置了无需权限的方法
  4. 使用方法级注解定义了特定的接口,如获取用户资料、更新用户资料和重置密码
  5. 所有接口都应用了 auth:sanctum 中间件进行认证
TIP

通过注解路由系统,我们可以非常清晰地看到每个接口的路由、权限和中间件配置,使得代码更加易读和维护。