October 1, 2022

『駅ログ!』をリリースしました!

こんにちは。

7月にiOS版、9月にAndroid版の駅乗りつぶし・口コミアプリ「駅ログ!」をリリースしました。 今日はそのアプリについて紹介したいと思います。

モチベーション

単純に、自分の趣味である「乗り潰し」の記録をしたかったからです。

社会人になってから駅の乗り潰しが趣味になっていました。いろんな駅を回るなら、その土地での体験を記録したいと思っていましたが、世の中にそれを記録できるような良い媒体がありませんでした。

なぜ体験を記録したいのか。

大学のときに読んだ、著名な建築家レム・コールハースの『S,M,L,XL』に影響され、土地のアイデンティティに以前から非常に興味があり、空間デザインとしての「駅」の役割には非常に興味を持っていたことが発端です。また、ソビエト連邦時代のバス停を収めたChristopher Herwig『Soviet Bus Stops』の写真集に、社会主義社会の公共インフラの創作性には感銘を受け、(バス停ではないものの)日本という資本主義国の駅のデザインには一種の諦念を感じていました。

その一方で、そんな日本でもそれぞれの土地には味があり、実はそれは「駅」を軸としているのではないかと思っています。その駅の空間に住む人、買い物などをしに出入りする人々、そこにいる人の佇まいや振る舞いは、駅の空間として形成されているのだと思っています。そして駅を軸として魅力を伝えることによって、その土地のアイデンティティが豊穣されるため、その触媒としてのメディアまたはSNSが必要だと考えていました。実際に、「錦糸町はいい街だよな」などの東京の各地域のイメージを駅ベースで連想したり(実際、錦糸町駅を軸に連想している人が多いと思います)、東京メトロも「駅」の中心とした魅力のためにいろんなPRをしています。 都内に住んでいる方だと、石原さとみさんが東京メトロの駅の魅力を紹介している動画を電車内で目にした人は多いのではないでしょうか。

このような空間が展開されているにも関わらず、口コミなどを掲載したりするプラットフォームはありません。前置きが長くなりましたが、このような問題意識があり本アプリの開発に至りました。

似たようなことをできるアプリだと駅メモが有名ですが完全に主旨が異なります。駅メモは「でんこ」と呼ばれるキャラを育成するゲームであると理解しています(課金も多く存在します)。素朴に、単純に駅を楽しんで乗り潰したいという趣味的な文脈だと、駅メモはあまりマッチしそうにありませんでした。副次的に乗り潰しを記録できますが、ゲームなので、体験の記録媒体としてみるといらない機能が多くあります。またグラフィックもアニメ的であり、好みが分かれると思います。アニメ的でないことは重要で、みんはやという老若男女に愛されていたクイズゲームがアニメ化したときには、自分の周りのほとんどの若者世代(弟)以外は嫌悪感を示し使わなくなりました。つまり、駅の乗り潰し記録がメインのアプリは実質ありませんでした。

また、紙媒体だといろいろあるのですが、現代に紙で記録するのはしんどいです。また、廃駅や新駅の発生などは年間で(意外と)多くあり、追従することは不可能です。無くすリスクがあったり、携帯する手間があったり、何より共有する手間があります。SNSがこれだけ発展した今、SNSに出力しづらい媒体は使い勝手が悪いと思っています。なんせ、駅の乗り潰しはTwitterなどでもよくツイートされており、他人と共有する・される喜びがあるものであるため、デジタルな媒体で残して置くのが良いはずです。

このようなモチベーションから、乗り潰しのためのアプリを作りたいと思い立ちました。

使っている技術

紆余曲折ありましたが、以下の技術を使っています。

  • Android
    • 100% Android Jetpack Compose
    • Dagger・Hilt
    • Material 2・3 (You)
    • Apollo Kotlin
    • GitHub Actions
  • iOS
    • 100% SwiftUI
    • Apollo Swift
    • Xcode Cloud
  • Backend
    • TypeScript
    • Cloud Run (GCP)
    • Prisma
    • OpenTelemetry
    • Apollo
    • Cloud SQL (Postgres)
    • Cloud Deploy

開発はすべて自分のみでやったため自分の独断です。

ポイント

いくつかのこだわった点があるので紹介します。

1. Serverlessでコストを最低限に

Minimum instanceを0にしたCloud Runのサービスでバックエンドはホスティングしています。 APIが呼ばれたときだけ実行される(ゼロスケールする)のでコストを最低限に抑えられます。今は1200人ぐらいのユーザーがいますが、ほぼ0円でサーバーをホストできています。

コールドスタートが懸念としてありますが、バックエンドのコンテナイメージを軽量化できるように常に意識していますし、Cloud RunのStartup CPU boostで「課金」をしているのでそこまで問題になっていません。

また、コールドスタートが懸念となるのは立ち上げ当初のみであると考えており、ユーザーが多くなればなるほどユーザーのリクエストに対してコールドスタートされる可能性が低くなるので、サーバーにかけるコストを抑えてユーザーを増やす方が(今のところ)有効的です。また、PrismaチームはPrisma Engine(Rust製)の起動時間の改善やバンドルサイズの軽減など、Serverlessで運用するための機能改善に本腰を入れてやっている様子で、直近でも大幅なスタートアップ時間の改善が見られています(直近のリリース)。

このように、サービスの立ち上げでコストをほぼ0円で抑えられいます。デメリットとして想定されるコールドスタートは現在は問題になっていないと思われ、かつ、将来的にはより改善する方向に進みそうなのでしばらくはServerlessの世界線で生きていけそうです。 私は本業がSREで、レスポンスタイムの定性的な分析などをすべきなので、手が空いたらしたいです。自分でアプリを触っている感じ、「コールドスタートにぶちあたったな」みたいな感触があるときはありますがStartup CPU boostのお陰でそこまで気になりませんでした。

普段、日記をつけるときを想定していただきたいのですが「記録をしたい」というときは時間を確保できている状態であることが多いため、あまり1秒ぐらいは気にならないのではないかと思っています。 うまくこのアプリを使うシーンとインフラ構成を調整できたのではないかと思っています。

主にコストとして発生しているのはデータベース (Cloud SQL)の料金です。 コストを抑えるならPlanetScaleやSupabaseなどのいわゆるServerlessなデータベースを使うことが考えられますが、行あたりの課金はコストまでスケールしそうで選択しませんでした。 Cloud Runと違って、クエリを何かしら間違ってしまったり、ループを余分(または無限)にまわしてしまったりしないことを保証するのは難しいなと感じていたので安全な方に倒しました。

2. それぞれのプラットフォームでPromisingな技術を使う

(執筆時に)モバイル開発をするなら他にもFlutterやKMM (Kotlin Mutliplatform Mobile)が代替案として挙げられると思います。 しかし、FlutterやKMMの勢い以上に、それぞれのプラットフォーマーがそれぞれのプロダクト (Android JetpackやSwiftUI)にモメンタムを持っている印象でした (これは完全に主観です)。

また、どうしてもプラットフォーム (iOSやAndroid)などの機能リリースなどの後手になることが多く、それも点もFlutterなどをいまいちと思っている理由です。

結果的に、特に特殊なことを実装していないこともあって、何も詰まることがなく、スムーズに開発をすることができました。以前、SpinpassというアプリをFlutterで開発したときは、そのコミュニティの未熟さに大変手を焼いたので、このようなことはプラットフォーマーが本腰を入れているプロダクトならではではないかと思っています (当時はFlutterFireやRiverpodなども黎明期でした)。もちろん、それぞれのOSで実装しないといけない手間はありましたが、GraphQLでSchemaファーストに開発していたため、UIの部分のみの開発がほとんどで、そこまでの工数はいりませんでした。

開発してみて

Androidに関しては、完全に何も知らないところからスタートしたのでしたので正攻法を掴むまで苦戦しました。Android Studioは多機能で覚えることがたくさんあります。初めてBuild variant, ComposeのPreviewを作り込んだりしました。Jetpack Composeの宣言的なところは非常に良かったです。これまで開発してきたFlutterやSwiftUIに通ずるものがあり、すぐにキャッチアップできました。Material 3を使えばアプリ全体を通して一貫したデザインに作り上げられ、エコシステムが整っているなと感じました。Jetpack Composeは今年安定版(1.0.0)が出たばっかりなので情報が少なく、苦戦することが多かったですが慣れてしまうと、旧来の方法(XMLなど)では開発できないと思うくらい快適な開発体験でした。思わぬところで苦戦したのがリリースのための審査です。とにかく遅いです。8日/1ラリーぐらいかかります。無法地帯と呼ばれていた時代は過去のもので、今では明らかにApp Storeより時間がかかります。

SwiftUIに関しては、今までiOSアプリを作った経験があるので特に何もなくスムーズに開発することができました。ちょうどXcode Cloudが出てきたところだったので使って見ましたが、最高に体験が良かったです。証明書などほとんどがマネージドでよく、(現時点で)無料枠もたっぷりあるのでバリバリ使えます。唯一、iOSアプリ開発の方で苦戦したのはSign in with Appleです。Google Sign inを提供しているので必然的にSign in with Appleも実装しなくてはなりませんでした。ユーザーの退会時に、AppleのAPIを叩いてAppleからもログイン情報を消さないといけないことが厄介でした…

BackendはTypeScriptやGraphQLなど慣れていた技術を使ったので特に苦戦することがなく、ぱっとできました。ApolloやPrismaを使えば(周知の事実なので改めて内容は書きませんが)本当に開発が楽なので、モバイルアプリの開発に時間を注ぐことができました。APIレイヤー、DBレイヤー、どちらもSchema-firstな開発をすることができ、どのプラットフォーム (iOS, Android, Node.js)でも一つのスキーマをもとに開発することができて、ビジネスロジックの実装に時間をつぎ込むことができました。

今後

ひとまず年内はクオリティを上げるところに注力します。そして、来年はより乗りつぶしを楽しめるアプリとして開発していければいいなと思っています。

© KeisukeYamashita 2023