Edited at

DartでWebAppの開発に必要なN個のこと

More than 5 years have passed since last update.

元ネタ

あるプログラミング言語で実際にWebAppを開発できるようになるまで、何が必要だろうか。言語仕様の習得は終えているとしよう。おそらく、最低限以下のような知識が必要だと思われる。とりあえずDartについて知っていることを書いた。←ここまで引用


パッケージマネージャ

標準のPubを使う。

プロジェクトルートの直下に以下のようなpubspec.yamlを配置し、pub installコマンドを実行することで依存パッケージをインストールできる。


pubspec.yaml

name: {プロジェクト名}

version: {バージョン}
environment:
sdk: {バージョン}
dependencies:
{パッケージ名}:{バージョン}
:
:
dev_dependencies:
{パッケージ名}:{バージョン}
:
:


アプリケーションサーバ

標準パッケージのioを使用すれば、HTTPサーバーを動作させることができる。


http_server.dart

import 'dart:io';

main() =>
HttpServer.bind('127.0.0.1', 8080).then((server) =>
server.listen((req) => req.response..write('Hello World!')..close()));

HttpServer abstract class

Apache HTTP Serverとのインタフェースはmod_dartが一番近道かもしれない。

コードを見る限り、 確実に Dartの構文エラーが発生するのでパッチを当てる必要がある。

そして(おそらく)誰も使っていない。


ルーティング

routeがシンプルで使いやすい。

このパッケージの面白いところは、サーバーサイドではHTTPリクエストに対するルーティングを、クライアントサイド(Webブラウザ)では Window. onPopState に対するルーティングを行えること。

URLの定義を一元化できるのが嬉しい。


lib/urls.dart(環境を問わず使用できる)

import 'package:route/url_pattern.dart';

final homeUrl = urlPattern(r'/');
final articleUrl = urlPattern(r'/article/(\d+)');
final allUrls = [homeUrl, articleUrl];


bin/server_side.dart(サーバーで動作する)

import '../lib/urls.dart';

main() =>
HttpServer.bind('120.0.0.1', 8080).then((server) =>
new Router(server)
..filter(matchAny(allUrls), authFilter)
..serve(homeUrl).listen(serverHome)
..serve(articleUrl, method: 'GET').listen(serveArticle));


web/client_side.dart(Webブラウザで動作する)

import '../lib/urls.dart';

main() =>
new Router()
..addHandler(homeUrl, showHome)
..addHandler(articleUrl, showArticle)
..listen();


データベース

まだデータベースアクセス用の統一的なインタフェースなどは用意されていない。

Pub のパッケージリストでデータベースアクセスをサポートするパッケージをピックアップしてみる。

開発が滞っているものもあるので、ご利用は計画的に。


RDMS系

MySQL:sqljocky

PostgreSQL:postgresql

ODBC:odbc

Google Cloud SQL:google_sqladmin_v1beta1_api


NoSQL系

Riak:riak_client

couchbase:couchclient


Webブラウザ系

localstorage, indexeddb, websql:lawndart


その他

ORM:dorm

memcached:memcached_client


ビューのレンダリング

最近はTemplatingもレンダリングと呼ぶらしいが、本来レンダリングするのはWebブラウザのレンダリングエンジ(ry

DartのWebAppでは、サーバーはHTML Templateを返し、Webブラウザ側で Single Page Application を構築する Thin-ServerSide アーキテクチャが基本となる。

そのため、需要がないためか、従来ながらのWebAppで使用されているようなサーバーサイドのTemplate Engineはまだ見当たらない。

今はPolymer.dartがアツい。

Dartを普段触らない人でも、 polymer , MDV(Model Driven View) , Shadow DOM , observe などの Web Component 周辺に興味のある人は、DartEditorをインストールしてサンプルアプリケーションを見てみると面白いかもしれない。

本来の意味での「レンダリング」に興味ある人には、標準パッケージのweb_glや、three.jsをポートしたthree.dartがある。


HTTPクライアント

Dart開発チーム製のhttpが使いやすい。

各種HTTPメソッドに対応したユーティリティ関数と、再利用可能なHTTPクライアントへの拡張の双方をサポートしている。


ユーティリティ関数例

import 'package:http/http.dart' as http;

main() =>
http.post('http://example.com', headers: {'token': token}, fields: {'username': 'you'})
.then((res) => res.bodyBytes.forEach(print));



HTTPクライアント拡張例

import 'package:http/http.dart' as http;

class OAuthClient extends http.BaseClient {
final String _consumerKey;
final String _consumerSecret;
final http.Client _delegate;

OAuthClient(this._consumerKey, this._consumerSecret, {http.Client delegate})
: this._delegate = delegate == null ? new http.Client() : delegate;

Future<http.StreamedResponse> send(http.BaseRequest request) {
request.headers['Authorization'] = buildAuthHeader(request, _consumerKey, _consumerSecret);
return _delegate.send(request);
}
}



テストフレームワーク

Dart開発チーム製のunittestmockを使う。

unittestはWebブラウザ環境もサポートしている。

もう少し、発展してほしいところ。


WAF

Rikuloがよく出来ている。

マルチデバイス対応のRikulo UI、サーバーサイドMVCアーキテクチャを採用したRikulo streamに、ストリームベースのメッセージプロトコル stomp をサポートするメッセージングサーバー実装のRippleまである。

ちなみに開発チームはJavaのAjaxWebアプリケーションフレームワーク、ZKと同じ組織らしい。

チームへのインタビュー動画が公開されているので、興味ある方はどうぞ。

Dartisans ep. 8: Rikulo Framework and Changes to Libraries and Imports


まとめ

以上。需要はほとんど無いかもしれませんが、個人的にまとめたかったのでやってみました。

Dartを全く知らない人でも雰囲気を掴んでもらいたく、サンプルコードを載せてみましたが、いかがだったでしょうか。

誤りや漏れなどが多分にあると思います。ご指摘のほど、よろしくお願い致します。