【後編】KotlinでWebアプリケーションを開発してみようハンズオン
WebアプリでHelloWorldを表示させてみよう
2日目は、KotlinでさくっとREST APIが作れる体験をゴールにハンズオンが行われました。まずは、IntelliJ IDEAとJDK、Kotlinプラグインなどがダウンロード・インストールできている確認から開始。全員の準備ができたところで、講義が始まりました。
KotlinのWebアプリケーションフレームワークには、主に以下の4つがあります。今回は「Ktor」を使ってハンズオンを進めていきます。
- Java Servlet
- Spring Framework (Spring Boot)
- Ktor
- Vert.x
Ktorは、JetBrains公式のフレームワークで、Spring Frameworkと比較すると機能は少なく、ロギング、永続化、テンプレートエンジン、DIなどはサードパーティ任せ。一方で、DSLに関しては、ラムダ(特に拡張関数としてのラムダ)が多様で、宣言的にプログラムを組み立てることができます。コールバックが多く複雑になりがちな非同期処理を、コルーチンによりasync-awaitのスタイルで記述可能にしてくれる特徴もあります
まずは、IntelliJ IDEAを起動し、KtorのProjectを立ち上げ、Hello Worldを表示するところからチャレンジします。Application moduleにコードや関数を記述。Webブラウザに「Hello, world」が表示されるまでのコードの記述について、図解の説明を聞きながら、一緒に手を動かしていきます。
タスク管理アプリの概要を学ぼう
続いては、いよいよタスク管理アプリの実装に入っていきます。今回作るタスク管理アプリは、タイトル・タスク(ボールペンを買う、発表スライドを完成するなど)・それらの説明画面・タスクが完了したかのチェックボタンなどで構成されています。
また、今回実装するAPIは、以下の3つとなります。
- タスクの一覧を取得するAPI:GET /tasks
- タスクを新規に作成するAPI:POST /tasks
- 既存のタスクを更新するAPI:PATCH /tasks/:id
タスク管理アプリ用に IntelliJ IDEAでKtorプロジェクトを新規に作り、Hello World APIを実装する課題に取り組みながら、次のトピックに進んでいきます。
まずはタスクそのものを表すクラスが必要なので、今回のアプリでタスクが持つべき属性を挙げてみます。
- タイトル
- 説明
- 作成日時
- 更新日時
- 完了済みか否か
- ID etc.
タスクには以下のように、様々な姿があります。
- APIレスポンス(JSON)としての「タスク」
- ドメイン上の概念としての「タスク」
- データベースにとっての「タスク」
それらを理解しながら、タスク一覧API(ダミー)を実装するハンズオンに取り組みます。
1.Taskクラスを実装する
└a.すべてのプロパティはvar
2.エンドポイント/tasksを定義し、ダミーのタスク一覧を返す
└a.JSON設定
└b.autoreload設定(Ktorのホットリロード設定)
└c.CORS設定
講師のお二人にアドバイスをもらいながら、タスク一覧APIを実装していきます。
続いては、コードを書く場所をコントローラとリポジトリに分けて実装する手順について説明が行われました。ここまでで午前中のハンズオンは終了し、お昼休憩に。
コントローラとリポジトリを実装するハンズオンに挑戦
午後は、午前中の続きで、コントローラとリポジトリを実装するハンズオンから開始されました。
大きく以下の4つの実装手順について説明を受けた後、それぞれで進めていきます。
- TaskRepositoryインタフェースを実装する
- DummyTaskRepositoryクラスを実装する
- TaskControllerクラスを実装する
- routingとコントローラを結びつける
ExposedでDBアクセスしよう
ここまではダミーのデータを返していたが、次は本物のデータをタスクに返して保存するDBを作成していきます。使うのは、JetBrainsが開発しているKotlin用DBアクセスライブラリ「Exposed」。
まだ安定版がリリースされていないので取り扱いに注意が必要ですが、面白い機能が多く、多くのRDBMSに対応しています。ExposedにはSQL DSLとDAO、2つの使い方が提供されていますが、今回はSQL DSLを使います。
Exposedを使った表現のポイントをコードを紹介しながら、わかりやすく講義を進めていく長澤太郎さん。日付の扱いなどの注意事項など、テーブルを実際に作成する手順を伝えていきます。説明を聞きながら、タスク一覧をDBにアクセスする作業も進めます。
- 依存ライブラリを追加する
- TaskTableクラスの定義
- テーブル作成コードの実装
- ExposedTaskRepositoryの実装
- 使用するリポジトリの切り替え
タスク作成APIを実装する
まずは、リポジトリに以下の作成メソッドを追加します。
- TaskRepositoryにinsertTaskメソッドを追加する
fun insertTask(task: Task)
- ExposedTaskRepositoryを実装する
override fun insertTask(task: Task) {
TaskTable.insert {
it[title] = task.title
...
}
}
続いて、タスク作成APIが受け取る中身をクラス化し、以下の手順で実装するハンズオンに取り組みます。(※2~5はコントローラー部分)ここまで完了すると、アプリが動くようになります。
- TaskCreateBodyクラスを実装する
- リクエストボディからTaskCreateBodyに変換する
- TaskCreateBodyからTaskに変換する
- TaskをTaskRepository#insertTaskを使ってDBに保存する
- 作成成功のステータスコードを返す
- ルーティング設定
タスク更新機能を実装しよう
まず、タスク単体取得APIの実装から入ります。ざっくり手順は以下となります。
a. リポジトリの実装(idからタスクを取得する)
b. コントローラの実装
c. ルーティングの設定
上記が実装できたら、パスに以下のパラメータを書きます。
get("/{id}") { taskController.show(call) }
val id = call.parameters["id"]?.toLongOrNull()
上記を書いたら再起動した後、フロントで表示されるか確認します。
続いて、タスク更新APIを実装していきます。
- /tasks/{id}に対してPATCHでリクエスト
- リクエストボディは
title: String
description: String
isCompleted: Boolean - Exposedで更新するには
TaskTable.update({ 条件 }) { insert時とほぼ同じ }
- 更新するときはupdatedDateTimeを現時刻に
最後に長澤さんは、「Kotlinを今後も学び続けてほしいし、Webアプリを作る際は技術的な選択肢の一つになってくれたら嬉しい。また、仙台でもKotlinのコミュニティや勉強会を増やし、どんどん盛り上げてください。みんなでKotlinを盛り上げていきましょう」と挨拶し、二日間のハンズオンを終えました。
二日間のハンズオンを終えた参加者の感想は?
今回の参加者の皆さんに、二日間のハンズオンを終えた感想を聞いたところ、Kotlinの基礎から実践的な内容まで幅広く学べたこと、業務でも活用できそうだという声をたくさんいただきました。
「Kotlinを全く触ったことのない初心者が学ぶのに丁度よいレベルだった」
「ちょうど業務でこれから行う内容と合致していたためとても参考になった」
「有料でも受けたいようなハンズオンを無料で受講できた」
「Kotlinの基本的な文法から、実際に動かせるアプリケーションを作るところまでを実践できたのがとても良かった」
「ハンズオンなので聞くだけでなく、実際に作りながら学ぶことができた」
「1日目が基礎で2日目が応用という流れが理解しやすく、プログラムの理解を深められる内容だった」
ハンズオン終了後、TECH PLAY運営から今後のイベントについて告知がありました。 仙台市では、今後もこうしたハンズオンや勉強会を開催していく予定です。 参加してみたいと思った方は、ぜひ、仙台市のグループをチェックしてみてください。
●仙台市主催のイベント
【12/7(土)~12/8(日)】SwiftでiPhoneアプリ作り体験!
【1/18(土)~1/19(日)】アプリUIデザイン実践ハンズオン
【2/7(土)~2/8(日)】デザインシンキング体験講座
【2/29(土)~3/1(日)】ビジネスプラン構築ワークショップ