Perfect 基礎編

サーバーサイドSwiftフレームワークのPerfectの使い方のメモその2

基礎編ではルーティングやリクエストの処理方法のあたりまで

URLルーティング

サンプルを見ると、ルーティングは大きくわけて

の2種類がある様子

設定はいずれもPerfectServerModuleInit()の中で行う

PageHandlerでのルーティング

Webアプリなどでの固定ページの表示向け
公式の参考になるサンプルはAuthenticator

例えば、http://0.0.0.0:8181/admin/というページを表示させたい時の流れとしては、

表示するページをmustacheのテンプレートで作成

例だとadmin.mustacheというファイル名にし、先頭のところでhandler:AdminHandlerと指定する
ポイントは、

テンプレートをプロジェクトへ追加

後述の小ネタにある「ドキュメントの配置」の方法で、admin.mustacheがドキュメントルートへ配置されるように設定する

PageHandlerを作成

ページにアクセスがあった時の処理を行う為のPageHandlerを継承したクラスを作る
(クラス名は任意だが、わかりやすいようにAdminHandlerとしておく)

作ったクラスをPageHandlerRegistry.addPageHandlerで登録する

PageHandlerRegistry.addPageHandler("AdminHandler") {
// (r: WebResponse) -> PageHandler in
  return AdminHandler()
}

ポイントは、

PageHandlerの中では、テンプレートに流し込む変数のDictionaryを生成する

RequestHandlerでのルーティング

APIとかブログのような動的なページ向け
公式の参考になるサンプルはURL Routing

例えば、REST APIでhttp://0.0.0.0:8181/user/mikeGETでmikeというユーザの情報を取得したい時の流れとしては、

ルーティングを設定

Routingでルーティングのルール(HTTPのメソッドやURLなど)をRouteMapを使って設定する

例だと、

Routing.Routes["GET", "/user/{id}"] = { _ in return UserHandler() }

となる。ポイントは、

RequestHandlerを作成

クライアントへ返すレスポンスを生成する為のRequestHandlerを継承したクラスを作る
(クラス名は任意だが、わかりやすいようにUserHandlerとしておく)

URLで指定されたユーザ名をそのままJSONで返す場合は以下の感じ

これで、http://0.0.0.0:8181/user/mikeにアクセスすると{ user: "mike" }と返ってくる

ルーティング設定の確認

Routing.Routes.descriptionで設定をダンプできる。これ、かなり便利!

リクエストの処理

URLパラメータやPOSTのボディの中身は、WebRequestの中に格納されている

http://0.0.0.0:8181/hoge?key1=value1&key2=value2とした場合、

func handleRequest(request: WebRequest, response: WebResponse) {
  request.queryString()  // key1=value1&key2=value2
  request.queryParams    // [("key1", "value1"), ("key2", "value2")]
  request.params()       // [("key1", "value1"), ("key2", "value2")]
  request.param("key1")  // value1
  request.param("key3", defaultValue: "value3")  // value3

POSTで{ "count"=100 }を送った場合、

func handleRequest(request: WebRequest, response: WebResponse) {
  let body = request.postBodyString
  let json = try! JSONDecoder().decode(body) as! JSONDictionaryType
  json["count"]  // 100

といった感じで取得できる

小ネタ

ドキュメントの配置

Xcode経由で起動している時に、サーバからドキュメントへアクセスできるようにする方法。なお、ドキュメントルートはデフォルトで./webroot/が設定されている

DocumentRootのパスを変更する

状況によってはソースから改変するのもアリだが、起動時に立ち上がるGUIから変更するのが手軽。Choose...でフォルダ位置を選択できる。 ただし、注意すべきなのはDocument Rootのテキストフィールド内でキー操作(return)しないと変更と認識されずに保存されない点 (これにはまってソースまで見てようやく気付いた・・・)。変更後はサーバの再起動が必要(というか勝手にされるはず)

この方法だとサーバを起動したままでもドキュメントを変更できるが、一方でパスの設定が必要となる

ビルドでファイルを配置する

前回の導入編で使った方法で、デフォルトの./webroot/を使いたい場合用

  1. 作成したプロジェクトを選択
  2. TARGETSでプロジェクト名と同じもの、Build Phasesタブを選択
  3. 左上のをクリックして、New Copy Files Phasesを選択
  4. DestinationProducts Directoryを選択
    Subpathwebrootと入力
  5. Nameの下の方にあるをクリックし、追加ファイルを選択してAdd
    (プロジェクトに未追加のファイルの場合はAdd Other...からで)

同一LAN内からのアクセス

例えば同じルータに繋がっているiPhoneから、Mac上で動いているPerfectのサーバに接続する方法

起動時に立ち上がるGUIのServer AddressをMacに割り当てられているIPアドレスに変更すればOK。 (変更後にreturnで確定を忘れずに・・・) ポートも変更できるが、80とかはroot権限が必要と怒られて変更できないので注意

(今回は既にDocker+nginxを構築してあったので、nginxのリバースプロキシの設定でさくっと対応)

感想

普段、クライアント(iOSアプリ)側で使っている開発環境と全く同じ環境でサーバの開発が出来るというのは、 想像以上に便利というかストレスフリーな感じ

もちろん、PerfectではCocoaが使えないというのはあるし、物足りない感じはしなくも無いが。。。

ただ、そのあたりのカバーを目指してのPerfectという命名なんだろうと勝手に想像

参考リンク

開発環境