この記事について
この記事はSwift Tweets (Swift Tweets 2018 Summer connpass) で発表したLTのまとめです。
後日swtws中に頂いた議論を元に追記予定です。
Kitura vs Vapor ?
"Server Side Swift -Kitura & Vapor-"というタイトルで発表をしました。@el_hrhmです。よろしくお願いします。
Kitura と Vapor を使って簡単なWebアプリを使ってみて感じたことについて投稿します。
作ったもの
- APIサーバー
- 静的HTMLを返すWebページ用のサーバー
- Reactを使ったシングルページのサーバー
それぞれをKitura, Vaporを使って作成し、比較してみました。
使い心地
結論としては、両者にスタイルの違いはあるものの、使い心地はどちらも良いと感じました。
両者はコーディングスタイルの違いもそうですが、Swiftの新しい機能の取り入れ方に差があります。
VaporはFutureを使って記述できるようにするなど、より使いやすくなるよう進化を速めている印象です。
一方Kituraはより進化の影響を外部に流出させないよう注意深く作られていて、固い印象を持ちました。
しかし、どちらも十分にドキュメントが充実しており、読めばやりたいことは大体できました。
(ドキュメントが膨大で、必要な情報を探し出すのに苦労するかもしれません。)
また、どちらのフレームワークも質問のための窓口があるので、困ったら投げてみると良いと思います。
(KituraはSlack, VaporはDiscord)
実際のプロダクトに適用するには、Kituraの方がプロダクトコードを変えずにバージョンを上げやすそうです。
しかし、より記述しやすい機能を提供するという点においてはVaporに軍配が上がると思っています。
どちらもまだまだ発展途上でこれから変わっていくので、どちらを採用するかは開発やプロダクトのスタイルが決め手になるでしょう。
How to Web Server
まず、クライアントからのリクエストに対してルーティングを記述します。どちらのフレームワークも簡単に記述できます。
APIサーバーであれば例えばJSON形式のレスポンス、Webページの表示ならHTMLや画像、jsファイルなどをクライアントに返します。
HTMLを返すサーバーであれば、コンポーネントを要求に応じて構築し、返す形にすれば良いでしょう。構造化された文書をSwiftで表現するのは可読性が高く、型による安全性も得られるので素晴らしいと感じました。
let html = """
<!DOCTYPE html>
<html>
\(htmlheader.html)
\(htmlbody.html)
</html>
"""
Webページではブラウザから要求されるリソースを返すようにサーバー側で定義する必要があります。こちらはKituraでのコードです。
適切なHTTPヘッダーを返す必要があるので、拡張子によって切り替えています。
app.router.get("/:filename") { request, response, next in
if let filename = String?(request.parameters["filename"]!){
response.headers.append("Content-Type", value: responseContentType(path: filename))
try response.send(fileName: "./dist/\(filename)")
} else {
response.statusCode = HTTPStatusCode(rawValue: 500)!
response.send("500 internal server error")
}
next()
}
シングルページであれば、webpackでbundle.jsを作るなどして、それをサーバーで返すようにすればできます。例えば以下のようにして、index.htmlでbundle.jsを要求するようにします。
app.router.get("/") { request, response, next in
response.headers.append("Content-Type", value: "text/html; charset=utf-8")
let filePath = "./dist/index.html"
do{
let str :String = try String(contentsOf: URL(fileURLWithPath: filePath))
response.send(str)
} catch {
response.statusCode = HTTPStatusCode(rawValue: 500)!
response.send("500 internal server error")
}
next()
}
まとめ
- KituraもVaporもいい感じ。好きな方でSSSしよう!
- 現状はAPIサーバーが良さそうです!