Fennec 是一个 Dart Web 框架,其主要目标是让 Web 服务器端开发更轻松、更快速。

pub
fennec (核心框架) fennec
fennec_jwt fennec_jwt

安装

  1. 创建一个简单的 dart 项目。您可以使用终端来完成 dart create ‘projectname’
  2. pub.dev 安装框架

发起您的第一个请求

创建您的第一个 RestController

@RestController(path: '/example')
class Test {
  @Route('/test', RequestMethod.get())
  Future test(Request request, Response response) async {
    response.send('hello world');
  }

  @AuthenticatedRoute('/template', RequestMethod.get(), MiddlewareHanlderImpl())
  Future testMiddleWare(Request request, Response response) async {
    response.render('template.html');
  }

  @AuthorizatedRoute('/authorization', RequestMethod.get(),
      MiddlewareHanlderImpl(), ['ADMIN'], UserProviderImpl())
  Future testAuthorization(Request request, Response response) async {
    response.render('template.html');
  }
}

Fennec Framework 有三种类型的路由

  • Route 是一个简单的路由,在请求执行之前没有其他执行或中间件。
  • AuthenticatedRoute 是一个需要中间件类的路由,开发者可以在其中定义所有必须在请求执行之前执行的操作和中间件(例如,验证令牌)。
  • AuthorizatedRoute 是一个需要中间件和用户授权类的路由,以及可以使用此请求的用户角色列表。此路由通常用于拥有许多用户角色的软件。

中间件

它必须是 **MiddlewareHandler** 类的子类型,以下是实现它的示例

class MiddlewareHanlderImpl extends MiddlewareHandler<MiddlewareHanlderImpl> {
  const MiddlewareHanlderImpl();
  @Middleware(priority: 0)
  Future<MiddleWareResponse> test(Request request, Response response) async {
    if (1 == 1) {
      return MiddleWareResponse(MiddleWareResponseEnum.next);
    }
    response.badRequest().send('not allowed second');
    return MiddleWareResponse(MiddleWareResponseEnum.stop);
  }

  @Middleware(priority: 1)
  Future<MiddleWareResponse> test1(Request request, Response response) async {
    if (1 == 1) {
      return MiddleWareResponse(MiddleWareResponseEnum.next);
    }
    response.badRequest().send('not allowed first ');
    return MiddleWareResponse(MiddleWareResponseEnum.stop);
  }
}

类中的每个中间件都必须用 @Middleware() 注释,并具有签名 Future ‘methodname'(Request request, Response response)。中间件也可以不使用 async 实现。priority 用于确定哪个中间件应首先执行。优先级越高,执行越早。

UserProvider

UserProvider 是一个接口,其中包含基于请求数据和 **AuthorizatedRoute** 中使用的角色的 loadUser 函数

UserProvider 的实现示例

class UserProviderImpl extends UserProvider {
  const UserProviderImpl();
  @override
  @AuthorizationRequired()
  Future<UserDetails?> loadUser(
      Request request, Response response, List<String> roules) async {
    if (!roules.contains('element')) {
      response.forbidden().send('not allowed');
      return null;
    }
    return UserDetailsImpl(1, 'tester', '[email protected]', '123456', []);
  }
  

class UserDetailsImpl extends UserDetails {
  UserDetailsImpl(id, String username, String email, String password,
      Iterable<Object> authorities)
      : super(id, username, email, password, authorities);

  @override
  UserDetails fromJson(Map<String, dynamic> map) {
    // TODO: implement fromJson
    throw UnimplementedError();
  }

  @override
  bool isAccountNonExpired() {
    // TODO: implement isAccountNonExpired
    throw UnimplementedError();
  }

  @override
  bool isAccountNonLocked() {
    // TODO: implement isAccountNonLocked
    throw UnimplementedError();
  }

  @override
  bool isCredentialsNonExpired() {
    // TODO: implement isCredentialsNonExpired
    throw UnimplementedError();
  }

  @override
  bool isEnabled() {
    // TODO: implement isEnabled
    throw UnimplementedError();
  }
}

WebSocket

WebSocket 已集成在框架的核心中。

如何使用

  
WebSocketHandler webSocketHandler = WebSocketHandler();
webSocketHandler.registerWebSocketHandler(server);
webSocketHandler.clientsListener.stream.listen((event) {
    if (event.headers!.value('token') != null) {
      webSocketHandler.addClient(event);
    } else {
      event.webSocket.addError('not allowed');
    }
  });
//Send data to all registred Clients
webSocketHandler.sendToAllJson({'key': 'value'});
  

启动您的服务器并测试您的第一个请求

import 'package:fennec/fennec.dart';
import 'package:path/path.dart' as path;

import 'test.dart';

void main(List<String> arguments) async {
  Application application = Application('0.0.0.0', 8080);
  application.set('cache', true);
  application.set('views', path.join(path.current, '/views'));
  application.addController(Test);
  Server server = Server(application);
  await server.startServer();
}

许可证

MIT

GitHub

查看 Github