现代Web应用程序的微框架,从shelf框架开始构建css
就像它的名字同样,Mojito主要是糖和其余成分的混合物。 Mojito故意在几个shelf包上很是薄,并专一于构建应用程序的总体体验。html
Mojito的重点是现代富Web应用程序,它们将ui与服务彻底分离。 所以,它不捆绑任何服务器端模板包,尽管能够轻松添加。java
Mojito的核心架构自己就是shelf。 全部组件都是现有的pub包,它们是从头开始构建的架构组件。 这使得利用未来出现的任何新的基于shelf的包很是容易git
要建立Web服务器并在端口9999上启动它,请在文件中键入如下内容并运行它。github
import 'package:mojito/mojito.dart'; main() { var app = init(); app.start(); }
你应该看到像这样的输出web
2015-06-28 13:03:27.123 [INFO] mojito: Serving at http://:::9999
这不会作任何有趣的事情,由于咱们没有添加任何路由。shell
让咱们如今解决这个问题api
main() { var app = init(); app.router.get('/hi', () => 'hi'); app.start(); }
此次当你启动时,你也应该看到相似的东西浏览器
2015-06-28 13:06:31.957 [INFO] mojito: GET -> /hi
用curl试试吧服务器
curl http://localhost:9999/hi
你应该看到'hi'的预期响应
Mojito有一个开发模式的概念,有助于快速开发循环。 默认状况下,它将根据环境变量MOJITO_IS_DEV_MODE激活开发模式。 您能够在shell提示符中激活它
export MOJITO_IS_DEV_MODE=true
初始化mojito时,您能够轻松覆盖开发模式的肯定方式。 例如
var app = init(isDevMode: () => true);
将它设置为始终打开。 一般你不想这样作。
若是在appengine上运行,则可使用如下命令设置开发模式。
var app = init(isDevMode: () => Platform.environment['GAE_PARTITION'] == 'dev');
Mojito配备了功能丰富的路由器。 您能够经过调用app.router来访问根路由器。 它支持多种样式来建立路由,例如:
@Get('{accountId}') Account find(String accountId) => new Account.build(accountId: accountId);
router.get('{accountId}', (String accountId) => new Account.build(accountId: accountId));
全部方式均支持:
要更好地了解您拥有的选项,请阅读博客文章中的路由选项。
mojito路由扩展了shelf_rest的路由器。 因为这在shelf_rest文档中有详细记载,所以我在此再也不重复。
此外,mojito还为如下任务提供路由方法。
静态资产(如html和css)是大多数Web应用程序的支柱。
在生产中,这些资产是从文件系统提供的,但在开发中,使用pub serve更方便。
Mojito容许您设置一个静态资产处理程序,在开发模式中和生产中的文件系统(有关激活的详细信息,请参阅开发模式一节)使用pub serve,这使得Mojito很是容易。
如下示例为使用/ ui开头的全部请求设置了一个路由,该请求使用pub serve(端口8080)和文件系统路径(build / web)的默认设置。
app.router.addStaticAssetHandler('/ui');
Mojito路由器提供了设置实现OAuth 2受权代码流的“客户端”部分所需路由的方法以及OAuth1的相似路由
这容许开发人员编写与启用OAuth的服务交互的Web应用程序,例如:
为了进一步简化这一过程,mojito支持多个开箱即用的受权服务器。如下示例显示了在使用memcache存储OAuth2数据在Google Appengine上部署时如何添加github客户端。
final oauth = app.router.oauth; oauth.gitHub().addClient( (_) => new ClientId('your clientId', 'your secret'), oauth.storage.memcache(() => context.services.memcache), new UriTemplate( 'http://example.com/loginComplete{?type,token,context}'));
您能够经过调用router.oauth来访问oauth的路由构建器。从那里你能够访问开箱即用的oauth存储(例如memcache和内存中的开发),以及用于常见受权服务器的自定义路由构建器,如github,google和bitbucket(PR欢迎更多服务器)。
对于其余(非开箱即用)受权服务器,请使用oauth.oauth2(...)或oauth.oauth1(...)方法。
当您启动上面的示例时,您将看到为github流建立的两个路由
2015-06-29 08:44:51.503 [INFO] mojito: GET -> /github/userGrant 2015-06-29 08:44:51.503 [INFO] mojito: GET -> /github/authToken
userGrant路由是您发送用户浏览器以启动流的位置。 它将重定向到github以供用户授予访问权限,github将把用户重定向回authToken路由。
成功完成身份验证流程后,用户浏览器将重定向回您提供的URL(本示例中为“http://example.com/loginComplete”),并相应地填充type, token 和 context 的查询参数。
在mojito中开始使用oauth的好地方是在mojito的示例文件夹中运行oauth.dart。
这为开箱即用的集成设置了路由。 而后,您能够经过向userGrant网址打开浏览器来尝试它
http://localhost:9999/oauth/github/userGrant
Mojito经过context属性提供一些内容,例如当前登陆的用户。 访问只需导入mojito。 例如
import 'package:mojito/mojito.dart'; somefunction() { print(context.auth); }
Mojito经过app.auth公开帮助程序来设置身份验证。 若是要将其应用于全部路由,请使用global构建器。
例如,如下内容将应用程序设置为使用基自己份验证,容许经过http进行访问(除了开发以外的一个坏主意)并容许匿名访问。
app.auth.global .basic(_lookup) ..allowHttp=true ..allowAnonymousAccess=true;
请注意,allowAnonymousAccess其实是一种受权形式(而不是身份验证),只是一种方便。 有关更多选项,请参阅下面的受权部分。
当前通过身份验证的用户(若是有)可经过mojito上下文得到。
它被定义为一个Option,若是没有当前通过身份验证的用户,则为None,若是有,则为Some。
例如,如下内容获取登陆用户的用户名(若是有),或者将其设置为“guest”。
app.router..get('/hi', () { var username = context.auth.map((authContext) => authContext.principal.name) .getOrElse(() => 'guest'); return 'hello $username'; });
要仅对某些路由应用特定身份验证,请使用auth builder()并使用所需路由上的命名参数middleware添加它。
var randomAuthenticator = (app.auth .builder() .authenticator(new RandomNameAuthenticator())..allowHttp = true).build(); app.router ..get( '/randomness', () { String username = context.auth .map((authContext) => authContext.principal.name) .getOrElse(() => 'guest'); return 'who are you today $username'; }, middleware: randomAuthenticator);
这里'/ randomness'路由有中间件:randomAuthenticator,它将该认证符应用于路由。
Mojito经过app.authorisation公开帮助设置受权。 与身份验证相似,若是要将其应用于全部路由,请使用全局构建器,不然使用builder()。
如下显示了如何强制只有通过身份验证的用户才能访问特定路由。 这颇有用,例如,若是您设置了容许匿名访问的全局身份验证器,而且您但愿阻止对某些路由的匿名访问。
app.router.get('privates', () => 'this is only for the privileged few', middleware: app.authorisation.builder().authenticatedOnly().build())
Mojito经过app.middleware公开帮助设置其余中间件。 与身份验证相似,若是要将其应用于全部路由,请使用global构建器,不然使用builder()。
它也很容易使用任何未与mojito捆绑的shelf包。
shelf包将暴露一个shelf Handler。 全部主要的mojito路由器方法都采用处理程序参数,所以很大程度上是将Handler从要集成的shelf包中插入到要使用的路由方法中。
若是程序包支持多个http方法,或者它只提供一个设置路径,那么应该使用add方法。
注意:若是您愿意,也可使用@Add注解
import 'package:mojito/mojito.dart'; import 'package:shelf_rpc/shelf_rpc.dart' as shelf_rpc; import 'package:rpc/rpc.dart'; main() { var app = init(); var apiServer = <create rpc apiServer somehow>; // create a shelf handler from the api var handler = shelf_rpc.createRpcHandler(apiServer); // create a route for the handler. app.router ..add('rpc', null, handler, exactMatch: false); app.start(); }
注意exactMatch:false是必需的,由于shelf_rpc提供了许多子路由。 还使用null做为methods参数的值,以便将全部方法传递给api。
Mojito捆绑了许多现有的货架库,并将它们集成以便于使用。 这些包括: