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



[元ネタ](http://d.hatena.ne.jp/gfx/20130909/1378741015 "PerlでWebAppの開発に必要なN個のこと") 

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

# パッケージマネージャ
標準の[Pub](http://pub.dartlang.org/ "Pub Package Manager")を使う。

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

```yaml:pubspec.yaml
name: {プロジェクト名}
version: {バージョン}
environment:
  sdk: {バージョン}
dependencies:
  {パッケージ名}:{バージョン}
   :
   :
dev_dependencies:
  {パッケージ名}:{バージョン}
   :
   :   
```


# アプリケーションサーバ
標準パッケージの[io](http://api.dartlang.org/docs/releases/latest/dart_io.html "dart:io")を使用すれば、HTTPサーバーを動作させることができる。

```dart: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](http://api.dartlang.org/docs/releases/latest/dart_io/HttpServer.html "HttpServer abstract class")

Apache HTTP Serverとのインタフェースは[mod_dart](https://github.com/sam-mccall/mod_dart "mod_dart")が一番近道かもしれない。
コードを見る限り、 **確実に** Dartの構文エラーが発生するのでパッチを当てる必要がある。
そして（おそらく）誰も使っていない。


# ルーティング
[route](http://pub.dartlang.org/packages/route "route")がシンプルで使いやすい。

このパッケージの面白いところは、サーバーサイドではHTTPリクエストに対するルーティングを、クライアントサイド（Webブラウザ）では `Window. onPopState` に対するルーティングを行えること。
URLの定義を一元化できるのが嬉しい。

```dart:lib/urls.dart（環境を問わず使用できる）
import 'package:route/url_pattern.dart';
final homeUrl = urlPattern(r'/');
final articleUrl = urlPattern(r'/article/(\d+)');
final allUrls = [homeUrl, articleUrl];
```

```dart: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));
```

```dart:web/client_side.dart（Webブラウザで動作する）
import '../lib/urls.dart';
main() =>
  new Router()
    ..addHandler(homeUrl, showHome)
    ..addHandler(articleUrl, showArticle)
    ..listen();
```

# データベース
まだデータベースアクセス用の統一的なインタフェースなどは用意されていない。
[Pub](http://pub.dartlang.org/ "Pub Package Manager") のパッケージリストでデータベースアクセスをサポートするパッケージをピックアップしてみる。

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

### RDMS系
MySQL：[sqljocky](https://github.com/jamesots/sqljocky "sqljocky")
PostgreSQL：[postgresql](http://pub.dartlang.org/packages/postgresql "postgresql")
ODBC：[odbc](http://pub.dartlang.org/packages/odbc "odbc")
Google Cloud SQL：[google_sqladmin_v1beta1_api](http://pub.dartlang.org/packages/google_sqladmin_v1beta1_api "google_sqladmin_v1beta1_api")


### NoSQL系
Riak：[riak_client](http://pub.dartlang.org/packages/riak_client "riak_client")
couchbase：[couchclient](http://pub.dartlang.org/packages/couchclient "couchclient")

### Webブラウザ系
localstorage, indexeddb, websql：[lawndart](http://pub.dartlang.org/packages/lawndart "lawndart")

### その他
ORM：[dorm](http://pub.dartlang.org/packages/dorm "dorm")
memcached：[memcached_client](http://pub.dartlang.org/packages/memcached_client "memcached_client")


# ビューのレンダリング

<del>最近はTemplatingもレンダリングと呼ぶらしいが、本来レンダリングするのはWebブラウザのレンダリングエンジ（ｒｙ </del>

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

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

今は[Polymer.dart](https://www.dartlang.org/polymer-dart/ "Polymer.dart")がアツい。

Dartを普段触らない人でも、 *polymer* , *MDV（Model Driven View）* , *Shadow DOM* , *observe* などの *Web Component* 周辺に興味のある人は、[DartEditor](https://www.dartlang.org/tools/editor/ "DartEditor")をインストールしてサンプルアプリケーションを見てみると面白いかもしれない。

本来の意味での「レンダリング」に興味ある人には、標準パッケージの[web_gl](http://api.dartlang.org/docs/releases/latest/dart_web_gl.html)や、three.jsをポートした[three.dart](http://pub.dartlang.org/packages/three "three.dart")がある。

# HTTPクライアント

Dart開発チーム製の[http](http://pub.dartlang.org/packages/http "http")が使いやすい。

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

```dart:ユーティリティ関数例
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));
```

```dart: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開発チーム製の[unittest](http://api.dartlang.org/docs/releases/latest/unittest.html "unittest")や[mock](http://api.dartlang.org/docs/releases/latest/mock.html "mock")を使う。

[unittest](http://api.dartlang.org/docs/releases/latest/unittest.html "unittest")はWebブラウザ環境もサポートしている。

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

# WAF

[Rikulo](http://www.rikulo.org/ "Rikulo")がよく出来ている。

マルチデバイス対応の[Rikulo UI](http://rikulo.org/projects/ui "Rikulo UI")、サーバーサイドMVCアーキテクチャを採用した[Rikulo stream](http://rikulo.org/projects/stream "stream")に、ストリームベースのメッセージプロトコル *stomp* をサポートするメッセージングサーバー実装の[Ripple](https://github.com/rikulo/ripple "ripple")まである。

ちなみに開発チームはJavaのAjaxWebアプリケーションフレームワーク、ZKと同じ組織らしい。
チームへのインタビュー動画が公開されているので、興味ある方はどうぞ。
[Dartisans ep. 8: Rikulo Framework and Changes to Libraries and Imports](https://www.dartlang.org/dartisans/dartisans-ep-8.html )

# まとめ

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

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

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