Kituraを使ってサーバーサイドSwiftを試してみた
はじめに
すごく久しぶりに投稿します。今後は、友人たちと投稿しようと思います。
今回は、Swiftを使ってサーバーサイドを書いてみたいと思い、IBM製フレームワークのKituraを使ってみた件について、toosaaがお話しします。
内容としては、Getting Startedを動かしてみるまでと、ちょっとした調査となります。
動作環境
- macOS High Sierra ver 10.13.3
- Xcode ver 9.2
- Homebrew 1.5.2
Getting Started
Getting Startedの手順に従います。2017年2月3日現在、同じことを書いているだけです。
事前準備
- Xcode9 のダウンロードとインストール
- Command Line Toolのインストール
$ xcode-select --install
- Homebrewのインストール
Kitura コマンドラインのインストール
$ brew tap ibm-swift/kitura
$ brew tap ibm-swift/kitura
プロジェクトの初期化
$ HelloKitura
$ cd HelloKitura
$ kitura init
- ここにあるように色々なファイルが作られます
- .gitignoreとかもあります
- この記事書いている時に、このページにCRUD projectやmodel generatorというのがあるのに気づきました。あとで読みます。
- ここにあるように色々なファイルが作られます
Hello, World!
$ open HelloKitura.xcodeproj
Sources/Application/Application.swift
のpostInit()
メソッドの中に下記のコードを挿入
注) 私の環境ではimport Kiture
のとこにNo such module 'Kitura'
とエラー出ましたが普通にビルドできます。
// Handle HTTP GET requests to / router.get("/") { request, response, next in response.send("Hello, World!") next() }
- ビルドスキームをHelloKituraに変更(デフォルトではHelloKitura-Packageになっているはず)
- Xcode左上の停止ボタン(四角いやつ)の右
- ⌘-Rで実行
- http://localhost:8080 にアクセス
これだけです。
調査
Hello, World!で書いたコードについて調べてみます。
routeの指定
routerはRouter Classのインスタンスで、getのオーバーロードをいくつか持ってます。そのメソッドの宣言を引っ張って来ると下記の通りです。参考
//RouterHTTPVerbs_generated.swift public func get(_ path: String?=nil, handler: RouterHandler...) -> Router public func get(_ path: String?=nil, handler: [RouterHandler]) -> Router public func get(_ path: String?=nil, allowPartialMatch: Bool = true, middleware: RouterMiddleware...) -> Router public func get(_ path: String?=nil, allowPartialMatch: Bool = true, middleware: [RouterMiddleware]) -> Router
今回使っているのは、これらの一つですが、下記のメソッドもあります。チュートリアルで使われています。
//CodableRouter.swift public func get<O: Codable>(_ route: String, handler: @escaping CodableArrayClosure<O>) public func get<O: Codable>(_ route: String, handler: @escaping SimpleCodableClosure<O>) public func get<Id: Identifier, O: Codable>(_ route: String, handler: @escaping IdentifierSimpleCodableClosure<Id, O>) public func get<Q: QueryParams, O: Codable>(_ route: String, handler: @escaping (Q, @escaping CodableArrayResultClosure<O>) -> Void)
上のget()は、クロージャーを使っていますが、@escapingがついていない&返り値があるので同期処理なのだろうと思います。反対に下のは、非同期処理で使うのだろうと思います。あとCodableなのでjsonのシリアライズでシリアライズ。
どちらにせよ、第一引数の文字列がurlに関るはずです。名前がrouteとpathで違うのはわかりませんが。
http responseを返す
Hello, Worldではresponse.send("Hello, World!")
でhttp responseを返していると予想できます。このresponseはRouterResponse classのインスタンスです。このclassのsend()は下記がとなっています。参考
public func send(_ str: String) -> RouterResponse public func send(data: Data) -> RouterResponse public func send(fileName: String) throws -> RouterResponse public func send(json: [Any]) throws -> RouterResponse public func send(json: [String: Any]) throws -> RouterResponse public func send(status: HTTPStatusCode) -> RouterResponse public func send<T : Encodable>(_ obj: T) throws -> RouterResponse public func send<T : Encodable>(json: T) throws -> RouterResponse public func send<T : Encodable>(jsonp: T, callbackParameter: String = "callback") throws -> RouterResponse
今回は一番最初のstringを返しています。静的なhtmlならsend(fileName: String), web apiならjsonのを使えば良さそうです。
next?
RouterHandlerの第三引数で、@escaping () -> Void
というクロージャーです。ドキュメントでは下記のように書かれています。ちょっと、コードを読んでみましたが、よくわかっていません(・_・;)
The closure to invoke to cause the router to inspect the path in the list of paths.
終わりに
今回は、KituraのGetting Startedと、その中で出てきたコードの簡単な調査を話しました。次回は、チュートリアルの内容に触れようと思います。