VaporとLeafを使ったサンプルアプリケーションの実装
はじめに
Vapor Advent Calendar 2018の2日目の記事です
今回はLeafを使って、サーバーサイドレンダリングを行うサンプルアプリケーションの実装をしていきます。
アプリの作成
まずはVaporのコマンドを使ってアプリの雛形を作成しましょう。
brew install vapor/tap/vapor
インストールが完了すると vaporコマンドで新しくアプリが作成できます。
vapor new sample-app
tree sample-app sample-app ├── Package.resolved ├── Package.swift ├── Public ├── README.md ├── Sources │ ├── App │ │ ├── Controllers │ │ │ └── TodoController.swift │ │ ├── Models │ │ │ └── Todo.swift │ │ ├── app.swift │ │ ├── boot.swift │ │ ├── configure.swift │ │ └── routes.swift │ └── Run │ └── main.swift ├── Tests │ ├── AppTests │ │ └── AppTests.swift │ └── LinuxMain.swift ├── cloud.yml └── web.Dockerfile 8 directories, 14 files
これでアプリの雛形が出来上がりました。
Xcodeで起動
続いてXcodeで起動できるように設定をしてきます。
といっても簡単でコマンドを2回実行するだけです。
cd sample-app vapor xcode
Xcodeで開くか確認されるので y
としましょう
Generating Xcode Project [Done] Select the `Run` scheme to run. Open Xcode project? y/n> y
Xcode上でRun(⌘+R)を実行し、localhost:8080
にアクセスするとアプリが起動できます。
アプリに起動が確認できました
Leafの設定
今回はHTMLテンプレートを使ったサンプルを作るので Leaf というライブラリを使います。
早速設定をしていきましょう!
Package.swift を編集して Leafを追加します。
// swift-tools-version:4.0 import PackageDescription let package = Package( name: "sample-app", dependencies: [ // 💧 A server-side Swift web framework. .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"), .package(url: "https://github.com/vapor/leaf.git", from: "3.0.0"), // 追加 // 🔵 Swift ORM (queries, models, relations, etc) built on SQLite 3. .package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0") ], targets: [ .target(name: "App", dependencies: ["FluentSQLite", "Vapor", "Leaf"]), // Leafを追加 .target(name: "Run", dependencies: ["App"]), .testTarget(name: "AppTests", dependencies: ["App"]) ] )
Xcodeを一度終了してターミナルからコマンドを実行してライブラリをダウンロードします。
vapor update -y
ダウンロードが完了したら、Leafを使う設定を記述しています。
configure.swift
import FluentSQLite import Vapor import Leaf // import を追加 /// Called before your application initializes. public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws { /// Register providers first try services.register(FluentSQLiteProvider()) /// Register routes to the router let router = EngineRouter.default() try routes(router) services.register(router, as: Router.self) /// Leafの設定を追加 let leafProvider = LeafProvider() try services.register(leafProvider) config.prefer(LeafRenderer.self, for: ViewRenderer.self) /// Register middleware var middlewares = MiddlewareConfig() // Create _empty_ middleware config /// middlewares.use(FileMiddleware.self) // Serves files from `Public/` directory middlewares.use(ErrorMiddleware.self) // Catches errors and converts to HTTP response services.register(middlewares) // Configure a SQLite database let sqlite = try SQLiteDatabase(storage: .memory) /// Register the configured SQLite database to the database config. var databases = DatabasesConfig() databases.add(database: sqlite, as: .sqlite) services.register(databases) /// Configure migrations var migrations = MigrationConfig() migrations.add(model: Todo.self, database: .sqlite) services.register(migrations) }
これで設定が完了しました。
サンプル画面を作ってみる
サンプル画面を作成してみましょう。
以下のようにテンプレートファイルを作成します。
※ 拡張子が.leafであることに注意してください
<!DOCTYPE html> <html> <head> <title>Leaf</title> </head> <body> <h1>Hello from Leaf.</h1> </body> </html>
続いてテンプレートとURLを紐付けるためにRoutingの設定をします。
/// Register your application's routes here. public func routes(_ router: Router) throws { // 省略 // 追加 router.get("hello") { req -> Future<View> in return try req.view().render("hello") } }
これでテンプレートを表示する設定が完了しました。
⌘+R でアプリを再起動しましょう
HTML ファイルの内容が画面に表示されました!!
動的な値を表示する
最後に構造体のデータを画面に表示してみます、
まずは動的にデータを表示するためのテンプレートを作成します。
続いて以下ように routes.swift
に追記をします。
public func routes(_ router: Router) throws { // 省略 // 追加 router.get("sample/todos") { req -> Future<View> in struct todos: Codable { let todos = [Todo(id: 1, title: "洗濯をする"), Todo(id: 2, title: "ご飯をつくる")] } return try req.view().render("todo", todos()) } }
⌘+R でアプリを再起動しましょう
構造体のデータが画面に表示されました!!
まとめ
- VaporでSwiftの構造体を画面に表示するところまで実装をしました。
- 実践的なアプリを作成する場合は、構造体のところをDBから取得した値に変更すれば実現できます。(時間の関係で今回はそこまでたどり着きませんした)
- SwiftはiOSでしか使わないような印象がありますがWebフレームワークもあるので実装してみましょう!!