現代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捆綁了許多現有的貨架庫,並將它們集成以便於使用。 這些包括: