aqueduct经验
注册数据库控制器
最后,您需要将数据库控制器注册到应用程序中:
import 'controller/user_controller.dart'; class YourAppChannel extends ApplicationChannel { ManagedContext context; @override Future prepare() async { final dataModel = ManagedDataModel.fromCurrentMirrorSystem(); final persistentStore = PostgreSQLPersistentStore( 'username', 'password', 'localhost', 5432, 'your_database_name'); context = ManagedContext(dataModel, persistentStore); } @override Controller get entryPoint { final router = Router(); router .route('/users/[:id]') .link(() => UserController(context)); return router; } }
创建数据库模型
注册数据库控制器 import 'controller/user_controller.dart'; class YourAppChannel extends ApplicationChannel { ManagedContext context; @override Future prepare() async { final dataModel = ManagedDataModel.fromCurrentMirrorSystem(); final persistentStore = PostgreSQLPersistentStore( 'username', 'password', 'localhost', 5432, 'your_database_name'); context = ManagedContext(dataModel, persistentStore); } @override Controller get entryPoint { final router = Router(); router .route('/users/[:id]') .link(() => UserController(context)); return router; } } 创建数据库模型 import 'package:aqueduct/aqueduct.dart'; class User extends ManagedObject<_User> implements _User {} class _User { @primaryKey int id; @Column(unique: true) String username; @Column() String email; } 创建数据库控制器 import 'package:aqueduct/aqueduct.dart'; import 'package:yourapp/model/user.dart'; class UserController extends ResourceController { UserController(this.context); final ManagedContext context; @Operation.post() Future<Response> createUser(@Bind.body() User user) async { final query = Query<User>(context)..values = user; final insertedUser = await query.insert(); return Response.ok(insertedUser); } @Operation.get() Future<Response> getAllUsers() async { final query = Query<User>(context); final users = await query.fetch(); return Response.ok(users); } @Operation.put('id') Future<Response> updateUser(@Bind.path('id') int id, @Bind.body() User user) async { final query = Query<User>(context) ..where((u) => u.id).equalTo(id) ..values = user; final updatedUser = await query.updateOne(); return Response.ok(updatedUser); } @Operation.delete('id') Future<Response> deleteUser(@Bind.path('id') int id) async { final query = Query<User>(context)..where((u) => u.id).equalTo(id); final deletedUser = await query.delete(); return Response.ok(deletedUser); } } 创建一个名为 auth_controller.dart 的控制器文件,并在其中实现用户验证的逻辑 import 'package:aqueduct/aqueduct.dart'; import 'package:aqueduct/managed_auth.dart'; class AuthController extends ResourceController { AuthServer authServer; AuthController(this.authServer); @Operation.post('username', 'password') Future<Response> login(@Bind.path('username') String username, @Bind.path('password') String password) async { final query = Query<User>(context) ..where((u) => u.username).equalTo(username); final user = await query.fetchOne(); if (user == null || !user.matchesPassword(password)) { return Response.unauthorized(); } final token = await authServer.authenticateForUser(user); return Response.ok(token); } } 在应用程序的主文件中,将创建的 AuthController 注册到路由中 import 'auth_controller.dart'; class MyAppChannel extends ApplicationChannel { ManagedContext context; @override Future prepare() async { final dataModel = ManagedDataModel.fromCurrentMirrorSystem(); final persistentStore = PostgreSQLPersistentStore(/* 数据库连接配置 */); context = ManagedContext(dataModel, persistentStore); } @override Controller get entryPoint { final authStorage = ManagedAuthDelegate<User>(context); final authServer = AuthServer(authStorage); return Router() ..route('/auth/token').link(() => AuthController(authServer)); } } 创建一个名为 auth_middleware.dart 的中间件文件,并在其中实现权限验证逻辑 import 'package:aqueduct/aqueduct.dart'; import 'package:aqueduct/managed_auth.dart'; class AuthMiddleware extends Controller { AuthServer authServer; AuthMiddleware(this.authServer); @override Future<RequestOrResponse> handle(Request request) async { // 从请求中获取 token final token = request.raw.headers.value('authorization'); if (token == null) { return Response.unauthorized(); } final validatedToken = await authServer.validateToken(token); if (validatedToken == null) { return Response.unauthorized(); } // 在请求上下文中存储验证通过的用户信息 request.attachments['user'] = validatedToken.resourceOwnerIdentifier; return request; } } 在应用程序的主文件中,将创建的 AuthMiddleware 注册到路由中作为全局中间件 import 'auth_middleware.dart'; class MyAppChannel extends ApplicationChannel { ManagedContext context; @override Future prepare() async { final dataModel = ManagedDataModel.fromCurrentMirrorSystem(); final persistentStore = PostgreSQLPersistentStore(/* 数据库连接配置 */); context = ManagedContext(dataModel, persistentStore); } @override Controller get entryPoint { final authStorage = ManagedAuthDelegate<User>(context); final authServer = AuthServer(authStorage); final router = Router() ..route('/auth/token').link(() => AuthController(authServer)) // 将 AuthMiddleware 注册为全局中间件 ..link(() => AuthMiddleware(authServer)) // 其他路由定义 ; return router; } }
代码示例
import 'aqueduct/aqueduct.dart'; class MyAppChannel extends ApplicationChannel { @override Future prepare() async { // 初始化数据库连接等操作 } @override Controller get entryPoint { final router = Router(); // 1. 网站端口为6081 router.route('/').linkFunction((request) async { return Response.ok('Hello, world!') ..contentType = ContentType.html; }); // 2. 使用orm接口进行数据增删查改访问,过程要求通过非ID字段进行查找数据 router.route('/items').link(() => ItemsController(context)); // 3. 使用token进行权限验证 router.route('/secure').link(() => SecureController()); // 4. 接收前端上传的图片文件并保存 router.route('/upload').link(() => UploadController()); return router; } } class ItemsController extends ResourceController { final ManagedContext context; ItemsController(this.context); @Operation.get() Future<Response> getItems(@Bind.query('name') String name) async { final query = Query<Item>(context) ..where((item) => item.name).equalTo(name); final items = await query.fetch(); // 5. 将数据库返回的false和true转化为可授权和不可授权后返回前端 final transformedItems = items.map((item) { return { 'name': item.name, 'authorized': item.authorized ? '可授权' : '不可授权' }; }).toList(); // 6. 返回前端的数据中带有前端自己的访问ip final clientIP = request.connectionInfo.remoteAddress.address; return Response.ok(transformedItems) ..contentType = ContentType.json ..write(clientIP); } } class SecureController extends ResourceController { @Operation.get() Future<Response> getSecureData() async { // 验证token逻辑 if (/* token验证通过 */) { return Response.ok('Secure Data'); } else { return Response.forbidden(); } } } class UploadController extends ResourceController { @Operation.post() Future<Response> uploadFile(@Bind.multipart('file') FileUpload file) async { // 保存上传的文件逻辑 final savedFilePath = /* 保存文件的路径 */; return Response.ok('File uploaded: $savedFilePath'); } } class Item extends ManagedObject<_Item> implements _Item {} class _Item { @primaryKey int id; @Column(unique: true) String name; @Column(defaultValue: 'false') bool authorized; } Future main() async { final app = Application<MyAppChannel>() ..options.configurationFilePath = 'config.yaml'; await app.start(numberOfInstances: 3); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix