はじめに
Swift がオープンソースになってからいろいろと盛り上がっているので、その中からサーバーサイド Swift の一つである IBM の Kitura を紹介します。
注意事項
Swift 3 と Kitura はともにまだ開発中のため、新しいバージョンだと記載内容と異なる部分がある可能性があります。 ここで使用したバージョンは以下のとおりです。
Software | Version |
---|---|
Swift | DEVELOPMENT-SNAPSHOT-2016-05-03-a |
Kitura | 0.16.0 |
Kitura とは
IBM が開発した Swift 用の Web フレームワークです。
Kitura の導入
- 適当なディレクトリを作成
作成したディレクトリの直下で以下のコマンドを実行
swift build –init
Package.swift を編集
import PackageDescription let package = Package( name: "KituraTutorial", dependencies: [ .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 0, minor: 16) ] )
swift build –fetch を実行し、Kitura のパッケージをダウンロード
お好みで Xcode を使ってコードを書きたいときは swift build –generate-xcodeproj を実行しプロジェクトファイルを作成
導入手順の解説
swift build –init を実行することで、アプリケーション開発のための下準備が行われます。 Swift Package Manager により以下のような構成でファイルが作成されます。
. +-- Package.swift +-- .gitignore +-- Sources | +-- main.swift +-- Tests
Package.swift は、Swift Package Manager でのマニフェストファイルです。 Package.swift にはビルドの設定や依存関係を記載します。 今回は Kitura を使用するので、以下のように依存関係に Kitura を追加します。
dependencies: [ .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 0, minor: 16) ]
Package.swift の書き方の詳細は、Package.swift — The Manifest File を参考にしてください。
swift build –fetch は、依存しているパッケージを取得するコマンドです。 このコマンドを実行すると、Packages ディレクトリ以下に依存しているパッケージがダウンロードされます。 また、依存しているパッケージの更新をするときは swift build –update を実行します。
アプリ作成
Sources/main.swift を編集してアプリを作成します。
モジュールのインポート
Kitura を使用するので、まずモジュールのインポートを行います。
import Kitura
ルーターの作成
アクセスする URL と、その URL にアクセスされた時に実行する処理を紐付けるためにルーターを作成します。 ルーターは、Router クラスのインスタンスです。
let router = Router()
アクセスされた時の処理の実装
GET や POST などのメソッドでアクセスされた場合の処理は、それぞれルーターの対応するメソッドを使用して定義します。
HTTP メソッド | Kitura |
---|---|
GET | get(_:handler:), get(_:middleware:) |
POST | post(_:handler:), post(_:middleware:) |
PUT | put(_:handler:), put(_:middleware:) |
HEAD | head(_:handler:), head(_:middleware:) |
DELETE | delete(_:handler:), delete(_:middleware:) |
OPTIONS | options(_:handler:), options(_:middleware:) |
TRACE | trace(_:handler:), trace(_:middleware:) |
handler は RouterHandler としてエイリアス定義されているクロージャで、実体は (request: Kitura.RouterRequest, response: Kitura.RouterResponse, next: () -> Swift.Void) -> Swift.Void となります。 middleware は、プロトコル RouterMiddleware のインスタンスを指定します。
エンドポイント /entry に GET でアクセスされた時の処理は、以下のような形で記述します。
router.get("/entry") { request, response, next in // GET の場合の処理 ... next() }
レスポンスとして、ステータスコードを指定したい場合は、response.status(_:) を呼び出します。 response.status(_:) は、列挙型 KituraNet.HTTPStatusCode を引数として受け取ります。 例えばステータスコード 403 (Forbidden) を設定したいときは、response.status(.forbidden) とします。
データの送受信
クライアントに送信する場合
メソッド | 送信データの種類 |
---|---|
send(_:) | 文字列 |
send(data:) | NSData |
send(fileName:) | ファイル |
send(json:) | JSON |
文字列を送信する場合は、以下のように書きます。
response.send("Some contents...")
Kitura では SwiftyJSON を使用しています。 JSON を送信する場合、SwiftyJSON を使用して JSON のオブジェクトを作成し send(json:) で送信します。
let dic = ["key": "value"] let json = JSON(dic) response.send(json: json)
クライアントから受信する場合
router.post("/entry", middleware: BodyParser()) router.post("/entry") { request, response, next in if let body = response.body { // POST の場合の処理 ... } next() }
ボディは列挙型 ParsedBody のインスタンスとして取得できます。 JSON とプレーンテキストを受信する場合、以下のように切り分けを行います。
switch body { case .json(let json): // JSON を受け取った時の処理 ... case .text(let string): // プレーンテキストを受け取った時の処理 ... default: break }
クエリー
クエリーは、RouterRequest のプロパティ queryParams に格納されています。 queryParams は [String:String] 型で定義されているので以下のように扱います。
if request.queryParams.contains({ return $0.key == "type" }) { let value = request.queryParams["type"] // クエリー "type" の処理 ... }
パラメーター
http://example.com/user/1234 にアクセスし、ユーザー ID 1234 のユーザーの情報を取得する場合を考えてみます。 この時、/user/:user_id の user_id というパラメーターの取得をルーターで行う必要があります。 このような場合は以下のように書きます。
router.get("/user/:user_id") { request, response, next in if let userID = request.params["user_id"] { // 指定したユーザー ID の処理 ... } next() }
上記の例では、["user_id":"URLで指定された値"] が request.params になります。 http://example.com/user/1234 にアクセスがあった場合には、["user_id":"1234"] がパラメーターになります。 request.params は、[String:String] として定義されていますので、数値などの文字列以外の型の場合は、ここから、さらに変換処理を行います。
HTTP サーバーの作成と開始
作成したルーターを使用して、HTTP サーバーの作成し、サーバーを起動させます。 サーバーの起動は、以下のように行います。
Kitura.addHTTPServer(onPort: 8090, with: router) Kitura.run()
ビルド
swift build を実行し、アプリをビルド。指定がない場合は、デバッグ版としてビルドされます。 リリース版をビルドする場合は、swift build –release を実行します。
実行
.build ディレクトリ以下にアプリは作成されます。
configuration | directory |
---|---|
デバッグ版 | .build/debug |
リリース版 | .build/release |
上記のディレクトリから、アプリを実行します。 アプリ実行後、http://localhost:8090/ にアクセスすると、動いているのが確認できます。
まとめ
今回はサーバーサイド Swift のフレームワークとして、IBM の Kitura を紹介しました。 Swift を触ったことがあれば、お手軽にサーバーサイドを実装できることがお分かりいただけたのではないでしょうか。