DartとRedstoneを使った簡単カスタムWEBサーバー (翻訳)


原題: Easy Custom Web Servers with Dart and Redstone
著者: [Monty Rasmussen](http://www.sitepoint.com/author/mrasmussen/)氏
原著公開日: 2015年06月25日
原著: http://www.sitepoint.com/custom-web-servers-dart-redstone/

この記事は[sitepoint](http://www.sitepoint.com/)の、[Monty Rasmussen](http://www.sitepoint.com/author/mrasmussen/)氏による記事の翻訳です。
怪しい日本語の表現が出てきた場合は、私の翻訳力不足ですので、ぜひ原文をご覧になってください。
また、誤訳を発見した方はコメント欄でご連絡いただければ修正します。

なお、この翻訳の公開にあたり、sitepointの Ophélie Lechat氏に許可をいただいています。
ありがとうございます！
Thanks Ophélie for permit!

これより下が記事の本文になります。

-----------

サーバーサイドのスクリプトに[Node.js](https://nodejs.org/)をつかうことは、現在はとても流行っていますし、[それだけの理由](http://blog.modulus.io/top-10-reasons-to-use-node)があります。

Node.jsはJavaScriptでつくられ、速く、イベントドリブンで、おそらくほとんどのWEBデベロッパーにとって良い選択肢ですし、もしもあなたが、フロントエンドを全てJavaScriptで記述しているなら、バックエンドでも同じ言語を使うことの利点は明らかです。

Node.jsには[Express](http://expressjs.com/)のような優れたサーバーサイドフレームワークがありますし、それによってカスタムWEBサーバーを、早く、そして簡単に作ることができます。


さて、もっと良い方法はあるでしょうか？


## Dartとは何でしょうか？

[Dart](https://www.dartlang.org/)はオープンソースの、スケーラブルで、オブジェクト指向プログラミング言語で、WEBサーバーやモバイルアプリを作るための、しっかりとしたライブラリとランタイムを備えています。
もともとはGoogleの開発者であるLars Bak氏とKasper Lund氏によって開発されていましたが、最近[ECMA標準](http://www.ecma-international.org/publications/standards/Ecma-408.htm)になりました。

Dartと、Dartのサーバーサイドフレームワークである[Redstone](http://redstonedart.org/)を使うと、Node.jsの利点とプラスアルファを享受することができます。
あとは、JavaScriptの奇妙な癖を忘れさることができますね。

Node.jsのように、DartのVirtualMachine(訳注:以後VM)もイベントドリブンで、非同期で、クライアントもサーバーもひとつの言語で、コードを共有しながら作る事ができます。
この場でほかのJavaScriptに勝る[Dartの利点の全て](https://www.youtube.com/watch?v=FqsU3TbUw_s)を述べていくことはしませんが(別の記事で書くかも)、もしもっと詳細な利点に興味があるようなら次のリストをみてください。

### Dartのアドバンテージ

* イミュータブルなオブジェクトとシンプルなセマンティクス、VMによる（高速化する）より良いコード最適化。
* [オプショナルタイプ](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#variables)と、final、constのサポート。
* オプショナルなデフォルト値を持つ名前付き引数をサポート。
* [静的スコープ(lexical scope)](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#functions)を持つ変数、クロージャ、this。
* 変数のhoisting(変数の巻き上げ)が無い。（訳注: hoistingについては文末に説明を付けてます。varのアレのこと）
* 代入や比較の際に型の強制がありません。
* No type coercion in assignments or comparisons.
* [Future (Promise) と Stream](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#asynchrony)。
* undefined は無く、null だけです。
* true だけが truthy です。
* 包括的な[標準ライブラリ](https://www.dartlang.org/docs/dart-up-and-running/ch03.html)を備えています。
* クラスのコンストラクタにおける[シンタックスシュガー](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#classes)で冗長性を減らします。
* 遅延ロードによるビルトイン[コードモジュール](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#libraries-and-visibility)をサポートします。
* Dartは[Observatory](https://www.dartlang.org/tools/observatory/)という、独自の高機能なプロファイラを備えています。
* ある開発者の経験が垣間見れる [Moving from Node.js to Dart](https://youtu.be/NHsmiY0rFS8?list=PLOU2XLYxmsIIQorIS8gagUiMau9S84vZV) を是非ご覧になってください。

これらのリストは単なる表面の傷にすぎません。Dart言語の短期集中コースとして [Dart: up and Running](https://www.dartlang.org/docs/dart-up-and-running/)をチェックしてみてください。
もしJavaScriptやJava、PHP、ActionScript、C/C++や他の "波括弧" 言語の知識があるなら、Dartはとても親しみやすく、1時間ちょっとでDartによってプログラミングを行えるようになるでしょう。
(訳注: 波括弧言語は、C系の構文のように `{}` が良く出てくる言語の事だと思われます）

## Get Dart

Dartの開発をサポートする[多数のエディタ](http://news.dartlang.org/2015/04/the-present-and-future-of-editors-and.html)がありますし、Dart開発チームは[JetBrainのWebStorm](https://www.jetbrains.com/webstorm/)対応を優先的に進めていくと発表しました。
他にも、簡単に（そして無料で）、[Sublime Text 3](http://www.sublimetext.com/3)に、[Dartプラグイン](https://github.com/guillermooo/dart-sublime-bundle)をいれて使うことで、このチュートリアルを進める事ができます。
いずれにせよ技術的にはまだベータ版ですが、それを利用する事をお勧めしています。

### ソフトウェアをダウンロードする

このチュートリアルを完了するためには、いくつかのソフトウェアが必要です。

#### Sublime Text 3

もしまだSublime Text 3をインストールしていない場合、使っているOSに合わせて最適なバージョンのものを[ダウンロードし、インストールして](http://www.sublimetext.com/3)ください。ちなみにこの記事を書いている時点での最新バージョンは3083でした。

#### Dart SDK

あなたのシステムに合わせた正しい[Dart SDK](https://www.dartlang.org/downloads/)をダウンロードしてください。ひとつ注意事項としては、このチュートリアルを実施するにあたってDartEditor（現在は非推奨）や [Dartium](https://www.dartlang.org/tools/dartium/)（Dart VMをのせたスペシャルエディションのChrominium）は必要ありません。

ダウンロードしたDart SDKをシステム内の適切なフォルダに解凍・設置してください。Windowsの場合、私は `C:\Program Files\dart\dart-sdk` に置きます。


### Sublime Text 3 の設定

Sublime Text 3を起動してください。その後、Dartのサポートを有効にするための設定を行う必要があります。


#### Package Control

もしまだ[Package Control](https://packagecontrol.io/)をインストールしていないのであれば、[このページの指示](https://packagecontrol.io/installation)に従ってインストールしてみてください。
注意点としては、インストール完了後にSublime Text 3を再起動する必要があります。

#### Dart Plugin

1. Sublime Text 3のメニューから、 Tools -> Command Palette... を選択し、「install」を入力してください。
1. ドロップダウンメニューから「Package Control: Install Package」を選択してください。
1. 「dart」と入力し、Dartパッケージを選択してください。注意点としては、全てのプラグインの機能を有効にする前に、Sublime Text 3を再起動する必要があります。
1. つぎにSublime Text 3のメニューから `Preferences` -> `Package Settings` -> `Dart` -> `Settings - User` を選択します。
1. 次のコードを `/path/to/dart-sdk` の部分をあなたのシステムの `dart-sdk` フォルダまでのパスに経校したうえで入力してください。

```sublime
{ 
  "dart_sdk_path": "/path/to/dart-sdk"
}
```

## Dartのプロジェクトを作成する

1. Sublimeのメニューから Tools -> Command Palette... を選択し、「Dart:」と入力します。
1. `Dart: Stagehand` を選択し、さらに`console-full` をコマンドラインアプリケーション作成のために選んでください。
1. Sublimeのウィンドウの下の方で、DartのStagehandツール(訳注:Dartプロジェクトのスケルトンを作成してくれるツール)が、どのパスに新しいDartのプロジェクトを作成するか聞いてきます。このディレクトリは新規ディレクトリか、空のディレクトリである必要があるので注意してください。今回は `redstone_intro` という名前にする事をお勧めします。

**注意:** もし処理中に「Stagehand is not enabled」というエラーを見た場合は、次のコマンドをターミナルで実行してくみてください。

```bash
cd /path/to/dart-sdk/bin
pub global activate stagehand
```

### 依存関係を解決します

さて、新しいプロジェクトが作成されたので pubspec.yaml というファイルを開いてください。Dartはプロジェクトが依存関係を管理するために pubspec というファイルを用いています。
開いたpubspec.yamlの中に既に書かれている「dependencies」セクションを、次のように変更してください（コメントである事を表す # から始まる行は全て削除してください）。

```yaml
dependencies:
  redstone: '>=0.5.21 <0.6.0'
```

ファイルを保存すると、Sublimeは自動的に [Pub](https://www.dartlang.org/tools/pub/) とよばれるDartのパッケージマネージャに指示を出し、Redstoneフレームワークを含む、全ての必要な依存関係を解決してくれます。
Pubは指定された範囲のバージョンのものを取得します。また、pubspec.yamlを編集中に F7 ホットキーを押すことでSublimeが同じように依存性の解決を行ってくれます。

Redstoneの詳細な情報やサンプルは、プロジェクトのGithubの[Wiki](https://github.com/redstone-dart/redstone/wiki)を見てください。

## Webサーバーを作る

簡単なサーバーをRedstoneで作ることは簡単です。
main.dart ファイルを開き(訳注: `bin/main.dart`)、既に記載されているコードを全て削除します。
そして、次のコードを記入してください。

```dart
import 'package:redstone/server.dart' as Server;
 
void main() {
  Server.setupConsoleLog();
  Server.start();
}
```

これがあなたにとって初めてのDartプログラムです。さぁ、1行ずつ見ていきましょう。
JavaやJavaScript、C#などの言語にくわしい開発者ならこれらの概念はおなじみでしょう。

```dart
import 'package:redstone/server.dart' as Server;
```

まず最初に、DartアナライザーにRedstoneの `server.dart` をコードから使う事を教えてあげます。
この特別な `package:` プレフィックスはPubで取得した依存関係である事を表しています。
（もし気になるなら、`packages` フォルダ内の、他のすべてのダウンロードされたパッケージを調べることができます。）
これによって、このDartプログラムのネームスペースに、Redstoneのクラスとトップレベル関数群をインポートします。
しかしそれは `start()` のようなよくある名前も含まれるため、カスタムネームスペース `Server` を `as Server` というシンタックスで設定します。

```dart
void main()
```

全てのDartプログラムはトップレベル関数の `main()` から処理が開始されます。
Dartはオプションで変数や関数の返り値の型を指定する事ができます。
そして `void` は `main()` が何も返さない事を示しています。

```dart
Server.setupConsoleLog();
```

RedstoneパッケージをServerというエイリアスでインポートしたので、Redstoneの関数を呼び出すときはその参照(訳注:`Server`のこと)を使う必要があります。
必ずしもこのエイリアスは必要ではありませんが、開発の手助けになります。
この1行はRedstoneフレームワークのコンソールログ出力をセットアップし、有益な情報などのRedstoneの実行ログをコンソール上に表示させます。

```dart
Server.start();
```

この行はRedstoneの `start()` 関数を呼び出していて、WEBサーバーを起動しています。
デフォルトでは `0.0.0.0:8080` (現在のIPの8080ポートの意味) をLISTENしていますが、これは設定で変更できます。

これでおしまいです！このサーバーはまだ意味のあるレスポンスを返してはいませんが、だとしてもちゃんとLISTENしています。`main.dart`で`Shift+F7`を押すとコードが実行されます。
コンソールログはSublimeの画面の下の方にある出力パネルに表示されます。

```text
INFO: <current date/time>: Running on 0.0.0.0:8080
```

アプリケーションを停止させたい場合は `Ctrl+Keypad0` (Ctrlキーとキーパッドのゼロ）を押すといいでしょう。

**Note:** ターミナルからサーバーの start/stop が行えます

```bash
cd /path/to/dart-sdk/bin
./dart /path/to/redstone_intro/bin/main.dart
```

SublimeでDartファイルの全てのコマンドを使うには、Sublimeのコマンドパレットが必要です（特にあなたのPCにキーパッドが無い場合には）。
Sublimeの Tools -> Command Palette... を選択し、「Dart:」を入力し、必要なコマンドを選択してください。そしてこれのショートカットが `Ctrl+. Ctrl+c` (2回連続で Ctrlと.を同時押しする)です。

もっとキーボードショートカットが知りたい場合は、Dartプラグインの[ショートカット](https://github.com/guillermooo/dart-sublime-bundle/wiki/Shortcuts)ページをご覧になってください。

## パスセグメントパラメータ

さて、サーバーがいくつかの要求に答えられるようにしてみましょう。
RedstoneのRouteアノテーションを使ってハンドラを作成することができます。

### Hello

つぎのコードを `main.dart` の末尾に追加してみてください(`main()` の後ですよ)。

```dart
@Server.Route("/hello")
String hello() {
  print("User soliciting greeting...");
  return "Hello, Browser!";
}
```

Redstoneを `Server` エイリアス付きでインポートしているので、`Server`への参照を含めるかたちで設定する必要がある事に注意してください。
(@から始まる)アノテーションは、次のリクエストがきたときに `hello()` 関数で、レスポンスする返り値を決めるよう、RedstoneのRouterに伝えます。

```
http://localhost:8080/hello
```

もしまだDartのサーバーが起動し続けていた場合は、サーバーを停止後に再起動し、ブラウザを開いてからURLを入力するとサーバーの結果が表示されます。
「Hello, Browser!」文字列を見る事ができるでしょう。また、`print()`を呼び出すと、有用なメッセージをコンソール上に出力する事ができます。

### Hi

他のRouteブロックを `main.dart` の末尾に追加してみましょう。

```dart
@Server.Route("/hi")
String hi() => "Hi, Browser!";
```

このコードは一つ前の例と似ていますが、とても短い関数を定義するためのファットアローシンタックス(訳注: `=>`のこと)を使っています。このように書かれているので、 `hi()` 関数は、矢印の次の計算式の結果を返します。この場合は文字列リテラルを返します。

この例をブラウザで試すには、次のURLをブラウザで開いてください。

```
http://localhost:8080/hi
```

## 高度なパスセグメントパラメータ

静的なパラメータを認めることは良いことですが、現実世界においては、カスタマイズされたレスポンスを得るためにダイナミックな値をサーバーに渡す必要があります。

### モックデータ

このあとのいくつかの演習のために、モックのデータベースと、いくつかのヘルパー関数となるデータモデルを追加しておきましょう。

`main()`の上、`import`の下に次のようにユーザーのリストを追加しましょう。

```dart
import 'package:redstone/server.dart' as Server;
 
List<Map> users = [
  {"id": "1", "username": "User1", "password": "123456", "type": "manager"},
  {"id": "2", "username": "User2", "password": "password", "type": "programmer"},
  {"id": "3", "username": "User3", "password": "12345", "type": "programmer"},
  {"id": "4", "username": "User4", "password": "qwerty", "type": "secretary"},
  {"id": "5", "username": "User5", "password": "123456789", "type": "secretary"}
];
 
void main() {
  Server.setupConsoleLog();
  Server.start();
}
```

Dartにおいて[List](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:core.List)は本質的な配列で、[Map](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:core.Map)はJavaScriptの標準のオブジェクト(あるいは `dictionary` や `hashmap` と他の静的型付け言語ではよばれます)のようなものです。
`users` 変数は、`List<Map>`シンタックスによって、`Map`要素の`List`である事が定義されています。
`[]` と `{}` をつかったシンタックスリテラルはJavaScriptプログラマーには馴染みやすいでしょう。
`main()`の上に`users`を定義したので、これはトップレベル変数になり、このファイル内の全ての関数内からアクセスする事ができます。


### ヘルパー関数

さて、ユーザーのリストの準備ができたので、サーバーからのレスポンスを整形する2つのヘルパー関数を定義することにしましょう。次のコードを`main.dart`の末尾に追記してください。

```dart
Map success(String messageType, payload) {
  return {
    "messageType": messageType,
    "payload": payload
  };
}
 
Map error(String errorMessage) {
  print(errorMessage);
 
  return {
    "messageType": "error",
    "error": errorMessage
  };
}
```

1つめの `success()`関数は、2つの引数を元に作られるMapを返します。
`messageType`はstringで、ユーザー一人のデータを返すのか、ユーザーのリストを返すのかによって、`"user"`か`"users"`のどちらかになります。
そのため`payload`パラメータは柔軟に型を変えられるように、あえて型宣言をしていません。Dartでは型指定が無い場合、デフォルトで`dynamic`型が適用されます。
	
つぎの `error()`関数も基本的には同じような事をしますが、エラーの状態を表現するのに十分なMapを返すようになっています。

ハンドラが単純な文字列のMapを返した際には、Redstoneフレームワークは自動的にJSONに変換してレスポンスしてくれます。


### ユーザーデータをユーザーIDから取得する

`main.dart`に新たなRouteハンドラを追加する準備が整いました。

```dart
@Server.Route("/user/id/:id")
Map getUserByID(String id) {
  print("Searching for user with ID: $id");
 
  // IDをStringからintに変換します
  int index = int.parse(id, onError: (_) => null);
 
  // エラーをチェックします
  if (index == null || index < 1 || index > users.length) {
    return error("Invalid ID");
  }
 
  // ユーザーデータを取得します
  Map foundUser = users[index - 1];
 
  // ユーザーデータをレスポンスします
  return success("user", foundUser);
}
```

このRouteは2つの静的パラメータ(user と id)を受け取り、もうひとつの動的なパラメータ(:id)を受け取るようになってます。`:`(コロン)シンタックスはリクエストユーザーが示す値をハンドラ側で受け取れるようにします。この関数のコードでは、あえて分かりやすくするために冗長なコメントを書いています。

```dart
print("Searching for user with ID: $id");
```

まず最初に、サーバーのコンソールにメッセージを出力しています。
`$id`シンタックスはDartのビルトイン文字列差し込み機能です（これについてはまた後で）。

```dart
int index = int.parse(id, onError: (_) => null);
```

つぎにListのインデックスを参照するときに使えるように、受け取ったIDをStringからintに変換しています。
`int.parse()`は、変換するための値と、オプショナルで、何らかのパースエラー時の振る舞いを表すコールバック関数を受け取ります。`onError`は名前付き引数で、コールバックはnullを返すファットアロー関数にしています。
コールバックは1つのパラメータを受け取りますが、今回はそのパラメータは使わないので、慣例として `_`エイリアスを利用して除外しています。
IDを正しくintにパースできなかった場合、onError関数の返り値が `index`変数にはセットされ、今回だと`null`がセットされる事になります。


```dart
if (index == null || index < 1 || index > users.length) {
  return error("Invalid ID");
}
```

もし`index`がリストの範囲外だった場合、"Invalid ID"というエラーメッセージが設定されたエラーオブジェクトを`error()`ヘルパー関数によって返します。

```dart
Map foundUser = users[index - 1];
return success("user", foundUser);
```

すべてが順調にすすんだ場合、このハンドラはリクエストに対してリクエストされたIDのユーザーデータをレスポンスします。
この`success()`ヘルパー関数によって、`messageType`が"user"で、`payload`がユーザーデータのMapオブジェクトを生成しています。

さて、確認のために次のURLをブラウザで開いてみましょう。

```dart
http://localhost:8080/user/id/5
```

リクエストしたユーザーデータを含むJSON文字列が結果として表示されます。

### ユーザーを Type で取得する

もうひとつハンドラを main.dart に追加してみましょう。

```dart
@Server.Route("/user/type/:type")
Map getUsersByType(String type) {
  print("Searching for users with type: $type");
 
  // 条件に適したユーザーを見つける
  List<Map> foundUsers = users.where((Map user) => user['type'] == type).toList();
 
  // エラーをチェックする
  if (foundUsers.isEmpty) {
    return error("Invalid type");
  }
 
  // ユーザーのリストを返す
  return success("users", foundUsers);
}
```

このRouteはIDではなくtypeによってユーザーを取得する事ができます。
ひとつのtypeに複数のユーザーが紐づくので、あらかじめ複数のユーザーを返せるようにしておく必要があります。

typeが一致するそれぞれのユーザーのMapオブジェクトのリストを作るために、 Listオブジェクトの標準関数である`where()`関数を使っています。
この関数には、そのリストの要素がひとつずつ渡ってくるので、要素をテストし、保持したい場合はtrueを返すような関数にしてください。
`where()`は実際にはListの祖先(クラス)である[Iterable](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:core.Iterable)を返しますので、`toList()`関数を使ってListに変換しています。
もしtypeが一致するユーザーが見つからなかった場合は、`foundUsers`は空のListになりますので、サーバーはエラーオブジェクトをレスポンスします。

この新しいRouteを確認するためのURLです。
2つのユーザーデータを含んだ配列のJSONが表示されます。

```
http://localhost:8080/user/type/programmer
```

## クエリーパラメータ

クエリー文字列のキーバリューのペアをRedstoneから取得するのはとても簡単です。

次のハンドラを `main.dart` に追加してください。

```dart
@Server.Route("/user/param")
Map getUserByIDParam(@Server.QueryParam("id") String userID) {
  return getUserByID(userID);
}
```

この例ではハンドラの引数 `userID` に、クエリーパラメータの `id` を渡すためのアノテーションをつけています。

```
http://localhost:8080/user/param?id=2
```

## 静的なページの配信

あなたがDartのサーバーから静的なページを配信したくなったらどうしましょうか？
ちょっとした行数のコードを追加するだけで、それは実現できます。

まず最初に、プロジェクトのbinフォルダと同階層にwebフォルダを作成します。
このwebフォルダの中に、`index.html`というHTMLファイルを作成し、次のコードを記載します。

```html
<!DOCTYPE html>
 
<html>
  <head>
    <meta charset="utf-8">
    <title>index</title>
  </head>
 
  <body>
    <p>Hello from index.html!</p>
  </body>
</html>
```

さらに、スムーズに事を進めるために、いくつかのパッケージをPubで取得します。
pubspec.yamlファイルを今一度開いて、dependenciesセクションを次のようにしてください。

```yaml
dependencies:
  redstone: '>=0.5.21 <0.6.0'
  shelf_static: '>=0.2.2 <0.3.0'
  path: '>=1.3.5 <1.4.0'
```

Redstoneは、GoogleのDartチームによって開発・メンテナンスされている低レイヤーなサーバーライブラリである、[Shelf](https://pub.dartlang.org/packages/shelf)を元に作られています。
これは、Shelfのミドルウェア（訳注:プラグインのようなもの。あるいはExpressのミドルウェアのようなもの）をRedstoneに追加して使うことが出来るという事です。
また、[path](https://pub.dartlang.org/packages/path)は、パス文字列をパースしたり操作するのに役立ちます。

Sublime はpubspec.yamlnい新しいdependenciesを追記して保存すると、自動的にPubを使って依存関係を解決してくれます。

これらのパッケージがプロジェクト内にダウンロードされ使えるようになったなら、`main.dart`の先頭にimportを追加してください。

```dart
import 'dart:io' show Platform;
import "package:path/path.dart" as Path;
import 'package:shelf_static/shelf_static.dart';
```

プラットフォームにアクセスするために、`io`というDartのコアライブラリをインポートします。
`show`キーワードを使うことで、`io`ライブラリに含まれるその他の I/O系の関数やクラスを無視して、Platformだけをインポートする事ができます。

`Path` ライブラリは一般的な名前のトップレベル関数を持っているので、`Path`という名前でimportするにあたって最適なパッケージです。

`main()`の先頭に新しく2つの行を追加します。(訳注:下のコード例では分かりやすいように改行しているので6行追加しています)

```dart
void main() {
  String pathToWeb = Path.normalize(
    "${Path.dirname(Path.fromUri(Platform.script))}/../web"
  );
  Server.setShelfHandler(
    createStaticHandler(pathToWeb, defaultDocument: "index.html")
  );
  Server.setupConsoleLog();
  Server.start();
}
```

サーバーを再起動後にサーバーのルート(root)に移動してみると、index.htmlを取得できます。


```
http://localhost:8080/
```

読者の皆さんが `Shelf` と `Path` について調べてほしいので前述の例の詳しい説明はしませんが、ここで、Dartのより便利な機能である、文字列補完について簡単に説明しておくべきでしょう。

文字列の中で `${}` リテラルを使うことで、計算式の結果を置くことができます。
式ではなくIDだけでよければ、$だけで良いです。(訳注:ココで言うIDは変数名とかのこと）

```dart
int myNumber = 5;
 
// 5 is my favorite number
String str1 = "$myNumber is my favorite number.";
 
// 5 + 10 = 15
String str2 = "$myNumber + 10 = ${myNumber + 10}";
```

## 最後に

このチュートリアルで、私は サーバーサイドにおける JavaScript、Node.js、Expressの素晴らしい代替手段について紹介しました。
Darは、数百万行のコードにスケールするために作られた、モダンで高速な言語です。
Redstoneは開発者ライフを簡単にする、たくさんのサーバーサイドフレームワークのひとつではありますが、私の大のお気に入りです。
なぜなら、サーバーの複雑な相互作用のための必要な定型文の量を、Dartのコードアノテーション機能を使って減らしているからです。

もしクライアントサイドも同じようにDartで書いた場合、サーバーとクライアントでコードを共有する事ができ、異なる言語で書かれたときのコンテキストスイッチの切り替えコストを避けることができます。
開発中には、JavaScript開発者が長年エンジョイしてきた Change-And-Refresh フローがすぐに使えるDartiumとよばれる特別なブラウザーを使うこともできます。
クライアントサイドのコードが完成したら、ちょっとクリックするだけで（あるいはコマンドラインを叩くだけで）、[dart2js](https://www.dartlang.org/tools/dart2js/)がDartのコードを、全てのモダンブラウザで動く、最小化し、結合し、Tree-Shaken(訳注: ※2）されたすぐにデプロイ可能なJavaScriptコードにコンパイルしてくれます。


Join the Dart side.

  
-------------------------

翻訳ここまで。
以下訳注に出てきた馴染みのないことばの説明です。

#### ※1 hoisting（巻き上げる）とは

```javascript
x = 5; //xに5を代入
var x; //xを初期化
console.log('x: ' + x); // x: 5
```

上記の例のように `var` より前に変数に代入し、その後　`var x` で初期化したように見えるのに、実際に行われる処理は `var x = 5;`と同じような動作になるJavaScriptの仕様のこと。
日本語で何て表現するのかはしらないが、`hoisting` と呼ぶらしい。
詳細は[Mozillaのドキュメント](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting)を参照のこと。

#### ※2 Tree-Shakenとは
Minification is not enough, you need tree shaking
http://blog.sethladd.com/2013/01/minification-is-not-enough-you-need.html

> 引用:
> Dart tools support tree shaking, a technique to "shake" off unused code, thus shrinking the size of the deployed application. I can import rich libraries chock full of useful goodness into my application, but only the functions I actually use will be included in my generated output. Awesome!

訳：
Dartのツールは tree shaking をサポートしていて、これは使ってないコードを振り落とすテクニックです。
これによってデプロイ時のアプリケーションサイズが小さくなります。
ぎっしりと有用な機能がつまったリッチなライブラリを自分のアプリケーションにインポートした場合も、生成されるコードには、実際に使っている部分だけが含まれます。素晴らしい！