はじめにの前に(概要/対象読者)
概要
- SwiftでサーバーサイドAPIの開発ができる
-> サーバーサイドの知識があまりなくても開発できちゃう - Swiftすごい、Vaoprすごい
対象読者
- Swiftの基本的なコーディングを経験した人
- サーバーサイド知識はあまりないが(Swiftを用いた)サーバーサイドの構築に興味がある人
※今回の勉強会で使用したコードは以下に置いています。Vaporで生成されたコードをちょっといじっただけですが。
https://github.com/s-kamada/Swift-server
あくまでレポなので勉強会の内容に合わせて記述します。
はじめに
今年の3月に大学を卒業し、4月からアプリを作る会社に入社した者です。
まだ研修期間中なのですが、研修では所定の要件に沿ったiOSアプリとAndroidアプリを製作しています。
先日研修のiOSアプリの製作が終了し、「Swiftの知見をさらに深めたい!」ということでこちらの勉強会に参加してきました。
iOSアプリエンジニアが挑戦する初めてのサーバーサイド(connpassリンク)
スライド(SlideShare)
大学時代にエンジニア志望の仲間として緒に勉強していた友人が講師役の勉強会です。
生粋のiOS/Swiftエンジニアですが普段は睡眠とAIを掛け合わせた研究をしているんだとか。
Swiftでサーバーサイドを作れるらしい
Swiftで書くと何がいいの?
- 早い
Swiftは4秒で終了しました。 Javaは4.3秒と、ほぼ同じぐらいです。このテストにおけるSwiftとJavaの性能はほぼ同じですね。Node.jsを見てみましょう。15.8秒かかっています。SwiftやJavaの約4倍ですね。Rubyはどうでしょう。とても遅いです。1
- 省メモリ
RSS(ベンチマークを実行するのに必要な物理メモリ領域)のベンチマークを見てみると、Swiftでは15MBで、Javaでは32MBです。必要なメモリはJavaの半分なのに、同じ性能です。Node.jsはJavaよりは若干少ないですが、Swiftよりずっと多いです。Rubyはたくさん必要ですね。1
なんでVaporなの?
Server-side-swift のフレームワークは数多あるけれど
- perfect
- Swifton
- Slimane
- Express
- HTTPSwiftServor
- Kitura
- Vapor etc......
主流はKitura、Vapor。
海外ではVaporの方がファンが多く、サーバーサイドの知識があまりない人はVaporの方がいい、ただしVaporの方がSwiftのアップデートへの対応が早いが、開発者もそれについていくためのコストがかかる、など長短あるようです。2
Vaporを使う
※ Homebrew、Swift/Xcode(4.1.0以上)がインストールされている前提です
構築
インストール
$ brew install vapor/tap/vapor
プロジェクト作成
$ cd [プロジェクトを置きたいディレクトリ]
$ vapor new [プロジェクト名]
プロジェクトを開く(Xcode)
すこし時間がかかります
$ vapor xcode
Generating Xcode Project...
Open Xcode project?
y/n> y
Opening Xcode project...
プロジェクト構成
基本的に編集するのはApp
フォルダ内のファイルです
Controllers
はコントローラ、Models
はモデルを入れるフォルダ、など見た通りの命名がされています。
コーディング(抜粋)
自動生成されたものだけも十分動きますが、ちょっといじります。
今回は「Todo管理アプリ」のサーバーサイドAPIを作成する前提で編集します。
モデル
final class TodoModel: SQLiteModel {
/// The unique identifier for this `Todo`.
var id: Int?
/// A title describing what this `Todo` entails.
var title: String
var isFinished: Bool
/// Creates a new `Todo`.
init(id: Int? = nil, title: String, isFinished: Bool) {
self.id = id
self.title = title
self.isFinished = isFinished
}
}
データモデルです。マイグレーション(自動的にデータベースの更新・管理を行う)などのextension
も実装できます。
コントローラ
final class TodoController{
/*中略*/
//新しいTodoを生成する
func create(_ req: Request) throws -> Future<Todo> {
return try req.content.decode(Todo.self).flatMap { todo in
return todo.save(on: req)
}
}
//すでに登録されているデータを更新する
func update(_ req: Request) throws -> Future<Todo> {
return try flatMap(to: Todo.self, req.parameters.next(Todo.self), req.content.decode(Todo.self)) { todo, updateTodo in
todo.title = updateTodo.title
todo.isFinished = updateTodo.isFinished
return todo.save(on: req)
}
}
}
データの読み込み、生成、削除の操作は自動で生成されますが、不足しているので更新処理を追記しました。
ルーティング
public func routes(_ router: Router) throws {
// そのエンドポイントのルートにアクセスした場合
// Basic "It works" example
router.get { req in
return "It works!"
}
// http://(エンドポイント)/hello/world にアクセスした場合
// Basic "Hello, world!" example
router.get("hello","world") { req in
return "Hello, world!"
}
// http://(エンドポイント)/todos に対してAPIを叩く場合
// Example of configuring a controller
let todoController = TodoController()
router.get("todos", use: todoController.index)
}
ルーティングを定義するファイルです。
ビルドしてサーバーを立てる
左上のバーをRun > My Mac
と設定してビルドします。この場合はlocalhost:8080
にサーバーが立ちます。
ターミナル上でもビルドが可能ですがXcode上でビルドするよりも時間がかかるようです。
$ vapor build
$ vapor run
動いたか確認してみる
ブラウザでlocalhost:8080
に移動してみると...
動いてるみたいですね
他のAPIも叩いてみます。ここからはAPIツールのPostmanを使用します
- 追加
- 一覧取得
まとめ
- サーバーサイドAPIをSwiftだけで簡単に作れる。やったね!
- 課題(今回の勉強会では触れなかったこと)
- DBとの連携が必要(今回はしていません。連携の設定をしないとXcodeを落とした際にデータがリセットされます)
- マイグレーションの方法
- デプロイ方法
-
Try! Swift NYCの講演より。現在は少し記録が更新されているようですが、やはりSwiftは早いかつ省メモリなようです(The Benchmarks Game) ↩ ↩2
-
ここやHacking with Swiftなど、KituraとVaporを比較考察している記事が多いです。 ↩