LoginSignup
3
3

More than 5 years have passed since last update.

Vaporのルーティングについて(応用編)

Posted at

動作環境
この記事では以下の環境で動作を確認しています。

  • Xcode9.0
  • macOS Sierra バージョン 10.12.6
  • MacBook Pro (13-inch,2017,Four Thunderbolt 3 Ports)
  • Homebrew 1.3.2
  • ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-darwin15.0]
  • Vapor Toolbox: 2.0.4
  • Vapor Framework: 2.2.2

ルーティング-グループ編

前回のVaporのルーティングについて(基礎編)ではルーティングの基礎をみていきました。

この章ではVaporのルーティングをグループ化する方法と1つのクラスで設定するコレクションを見ていきたいと思います。
この方法を利用すれば、WebAPIを設計する際にバージョン指定が簡単にできるようになり、また可読性の高いアプリケーションが作成できます。

Groupメソッド

Dropletgroupメソッドを実行するとクロージャーにRouteBuilderが渡されます。
これにエンドポイントを設定することでルーティングをグループ化することができます。

GET /v1/usersGET /v1/users/:id(idはInt型)を設定してみます。

drop.group("v1") { v1 in
   //GET /v1/users
    v1.get("users") { req in
        return "users"
    }
    //GET /v1/users/:id
    v1.get("users", Int.parameter) { req in
        let userId = try req.parameters.next(Int.self)
        return "You requested User #\(userId)"
    }
}

ビルドしてローカルでサーバーを起動してみます。

$ vapor build
$ vapor run

http://0.0.0.0:8080/v1/users/
にアクセスするとusersという文字列が返却されます。

http://0.0.0.0:8080/v1/users/1
にアクセスするとYou requested User #1という文字列が返却されます。

Groupedメソッド

GroupedメソッドはRouteBuilderを返却します。
先程の例をv2以下に設定し直してみます。
GET /v2/usersGET /v2/users/:id(idはInt型)のエンドポイントを作成します。

let v2 = grouped("v2")
v2.get("users"){ req in
    return "users"
}
v2.get("users", Int.parameter) { req in
    let userId = try req.parameters.next(Int.self)
    return "You requested User #\(userId)"
}

先程と同じようにビルドしてローカルでサーバーを起動してみます。

$ vapor build
$ vapor run

http://0.0.0.0:8080/v2/users/
にアクセスするとusersという文字列が返却されます。

http://0.0.0.0:8080/v2/users/1
にアクセスするとYou requested User #1という文字列が返却されます。

これを利用することで、Web APIのバージョン指定が簡単に実現できるでしょう。

ルーティング-コレクション編

ルーティングの基礎編とグループ編でルーティング指定について説明しました。
ここではルーティング指定を一つのクラスにまとめる方法をみていきます。

RouteCollectionプロトコルを適応するクラスを作成すると、ルーティング指定を一つのクラスにまとめることができます。

GET /v3/usersというエンドポイントとGET /v3/articlesというエンドポイントをRouteCollectionに適応したクラスV3Collectionで作成してみます。

 import Vapor
 import HTTP
 import Routing
 class V3Collection: RouteCollection {
     func build(_ builder: RouteBuilder) {
         let v3 = builder.grouped(v3)
         let users = v3.grouped(users)
         let articles = v3.grouped(articles)
         users.get { request in
             return Requested all users.
            }
         articles.get(Article.init) { request, article in
             return Requested \(article.name)
            } 
        }
}

ルート設定をクラスにすることでどんな場所でも記述することができるようになり可読性が高まるでしょう。
Dropletクラスのcollectionプロパティにこのクラスのインスタンスを渡すことでルーティングを追加できます。

let v3 = V3Collection()
drop.collection(v3)

Dropletがルートコレクションのbuild(_:)に渡されてルーティングが追加されます。

初期化で何もしない場合

ルートコレクションの初期化で何もしない場合はEmptyInitializableも適応することができます。
そうするとルートを追加する際に型を指定するだけで追加できるようになります。

 class V3Collection: RouteCollection,EmptyInitializable {
     init() { }
...

こうすると、Dropletにルートを追加するとき、インスタンス化しなくてもよくなります。

drop.collection(V3Collection.self)

参考

Route Groups
https://docs.vapor.codes/2.0/routing/group/

Route Collections
https://docs.vapor.codes/2.0/routing/collection/

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3