サーバサイド Swift でウェブページを運用している話

[ドワンゴ Advent Calendar](http://qiita.com/advent-calendar/2016/dwango) 7 日目の記事です。
昨日は ru_shalm さんの [「React Native for Androidでアプリを作ったときにハマったこととかの話」](http://qiita.com/ru_shalm/items/9dbe52d00b90c85bd4b9) でした。
iOS の React Native でちょっと遊んでみたことはありますが、普段から iOS 開発をしている自分は普通に Swift で書きたいなと思いました（すみません）。
でも普段 JS でバリバリやっている人は馴染みのある言語だととっつきやすいですよね。
今日もそんな話です。

# これはなに

みなさんは何かしらの方法で自分のウェブページを持っているかと思いますが、どんな環境でやっていますか？
私は馴染みのある言語である [Swift](https://swift.org) でサーバを書いています。

以下がまとめです

- 言語は Swift を採用した
- 簡単なルーティングをして静的ファイルを返すだけのサーバを立てた
- 6ヶ月間無停止で何事もなく動いており快適

ホームページはこちらです: https://mokumoku.cloud
リポジトリはこちらです: https://github.com/mokumoku/MokuMokuCloud

# サーバサイド Swift

長らく mokumokucloud.net という URL でやっていたのですが、 `.net` って何よ、という話になり gTLD 一覧を眺めていたところ `.cloud` というドメインがあったので「これは」と思い mokumoku.cloud を取得しました。
この機会にリニューアルをしようと思い、フル AWS で構築をしてサーバサイドも自分で書くことにしました。
その際に選んだのはもちろん Swift でした。最も使い慣れた言語の方がコストも少なく済みますしね…

### 閑話

URL が変わってリニューアル。
ゲームキュレーションサービス「[電ファミニコゲーマー](https://df.nicovideo.jp)」という面白いサービスがあります。

(サーバサイドは Node.js が使用されています。)

### 閑話休題

サーバサイド Swift フレームワークもいろいろあって戦国時代ですが、 [Kitura](https://github.com/IBM-Swift/Kitura) を使用しました。
IBM 製ということで Swift のバージョンが上がってもメンテされそうというのが理由です。

## AWS で動かす

構成はこんな感じです。

![20160530213923.png](https://qiita-image-store.s3.amazonaws.com/0/56442/2764460e-1e6c-315e-4cc3-8e119fd13fe6.png)

サーバサイドは専門ではないので詳しいことは割愛させてもらいますが、簡単にいうと EC2 が一台立っているだけです。
ELB はスケールさせるためではなく、 HTTPS 化のための証明書おき場のために立てています。（もちろん Auto Scaling してもいいんですが、当然そんなアクセスがあるわけでもなく、アクセス過多で落ちても誰も困らないのでこれでいいのです。お金もないです。）
あとは CodeDeploy というサービスがあったので、 GitHub にプッシュしたらフックしてデプロイができるようになればいいのですが、まだ IAM への理解が足りないのか毎回失敗しています。

# 簡単なルーティングをして静的ファイルを返すだけのサーバ

自分のウェブページは静的な HTML を返すだけなので、正直 S3 に置けば事足ります。
それでは悔しいので、ルーティングをして URL を綺麗にしています。

```
例： /about.html は /about でアクセスできる
```

これは以下のように書けます。

```swift:main.swift
private func redirectHtml(_ name: String, _ response: RouterResponse) {
  do {
    response.headers["Content-Type"] = "text/html; charset=utf-8"
    let path = "./public/\(name).html"
    try response.status(.OK)
      .send(fileName: path)
      .end()
  } catch {
    Log.error("Failed to link \(name).html")
  }
}

router.get("/about") { request, response, next in
  redirectHtml("about", response)
  next()
}
```

はい、 `/about` への GET アクセスが来たら `about.html` を返すだけです。
このようにページの分だけ当該の HTML ファイルを返す処理を書けば完成です。

# 立てた後の話

6か月間何も触らずにおいたのですが、落ちたりすることもなく平和に稼働していました。
単純に Kitura が優秀でメモリリークを起こさなかったということだと思います。
アクセスは平均すると 2 ユーザ/日 くらいなので負荷はゼロです。

AWS でやろうとすると、Swift を扱える環境は EC2 しかありません。さらに HTTPS にするために ELB を立てなければならず、お金はとてもかかります。
何もしなくても月 3000 円くらいかかるのでお財布には大変優しくないです。

# ちょっと真面目に考察してみる

趣味の過疎ウェブページを作ったところで、何でやっても結果は変わらないと思うので「サーバサイド Swift はお仕事で使えるレベルか？」を想像してみたいと思います。

### 開発のしやすさ

Swift で開発をしたことがある人であればもちろんやりやすいです。
しかし Xcode を使った開発は少々やりづらさを感じたので別のエディタを使うことになるかと思います。

#### ライブラリ

[Swift Package Manager(SPM)](https://swift.org/package-manager/) を使用します。
CocoaPods や Carthage に対応していても SPM に対応しているライブラリはまだ少ないです。
とはいえ SwiftyJSON, RxSwift, Alamofire などの有名どころは対応しているので大体 iOS と同じように開発できるかもしれません。

しかし、 iOS になかったもの、例えば O/R マッパやテンプレートエンジンなどはまだまだよくわからん（あるにはあります）状態なのでとても手軽にウェブサービスが作れるという状態には程遠いでしょう。

### 保守性

こちらはサーバの言語というよりもサーバのアーキテクチャの話になるかと思います。
ただし、 Swift のアップデートが早いというのは障害になるかもしれません。

先ほど 6 か月間何も触らずにおいたと書きましたが、その間に Swift は 2.2 から 3.0.1 になっており、 Kitura も 0.4 から 1.3 になっていました。
軽く浦島状態だったので API を一からググることになりました。
また Swift の管理を [swiftenv](https://github.com/kylef/swiftenv) で行っていますが 3.0.1 がインストールできず困りました。
（swiftenv を入れ直したらインストールできました）

というように、半年間放置するのはプロダクトでは早々ないことだと思いますが久しぶりに触ると大きな変更があり、ビビる
ということはあるのでアップデートはこまめに追従しなければいけません。

_iOS アプリでも Swift のバージョンアップで変更点が多く、ビルドを通すので一苦労なのでこまめに対応したほうがよく、マイナーバージョンを一つ飛ばすだけでも大変な苦労をしている人もいるようです。_

#### 閑話

電ファミニコゲーマーには [iOS アプリ](https://itunes.apple.com/jp/app/denfaminicogamer/id987476918?mt=8)もあるので使ってみてはいかがでしょうか。

#### 閑話休題

というように実用的なものを作るにはまだ時間がかかりそうという感想ですが、Swift でウェブページが表示できるというだけで嬉しいので是非挑戦してみてはいかがでしょうか。

# まとめ

- Kitura でウェブページを表示できるようにした
- サーバサイド Swift で複雑なものを作るのは厳しい
- が、 Swift を使うシチュエーションが増えて嬉しい

最近キャッチアップできていなかったので、サーバサイドで素晴らしいフレームワークなどができていたらコメントで教えていただけるととても助かります。