この記事はQiita 個人開発 Advent Calendar 2022の12/11の記事になります。
こんにちはjunです。2022年の11月にRouteShareというユーザー投稿型webサービスをリリースしました。地図に情報を入力し、ワードプレスの様に記事を作成し、いろんな道や場所の魅力を投稿できます。ユーザーが自由に地図に情報を入力して地図を見ながら記事を読めること、地図(地理情報)を中心としたコンテンツです。ツーリスト、サイクリスト、ライダーなど、いろんな場所に旅行したり地理情報をまとめる人向けになっています。ぜひご興味ありましたらご利用ください。メールアドレスかGoogleアカウントで登録が可能です。RouteShareについてより知りたい方はこちら
さて、宣伝はここまでにしておきます。このサービスは企画、設計、デザイン、実装、デプロイ、支払い全てに至って自分で行った、個人開発プロダクトです。途中、友人にコンセプトや使い心地のレビューはもらいましたが基本的には一人で開発しました。開発開始から9ヶ月で作り上げたサービスで、これからは運営や改善を繋げながら収益化を目指そうと思っています。
今回の記事ではリリースに至るまでの、企画、設計、デザイン、実装、デプロイ、支払いなど実務的な内容を書こうと思います。結構長くなると思いますが、個人開発をしてみたい人の参考になればと思います。適宜、好きなセクションに飛ばしてみてみてください。
人によっては「個人開発」の意味合いやどこまでやるかという感覚が異なると思いますので、あらかじめここで解説する「個人開発」というものを定義しておきます。
ここでいう個人開発は
としておきます。そのため
といったことではないとしておきます。まあ「法人格を持って運営する」あたりは「事業として収益化を目指すもの」とぶつかったりするので、あくまで「こんぐらいのレベル感なんだなー」と思ってください。
また、作成するサービス種別はwebサービスとしておきます。ただしある程度のセクションはネイティブ開発など他種別の個人開発にも応用できると思います。
2022年の2月から同年11月にリリースしました。退勤後や土日を使用して作成したので、期間は9ヶ月かかりました。アプリケーションの構成自体はそれほど複雑でないので、実際は3人月ぐらいでできそうな規模です。
内訳としては
という感じです。構想自体は結構前から練っていたのでそれほど時間はとりませんでした。
公開サービスなのでセキュリティ上可能限りで紹介します。
フロントエンドは得意なNuxt.jsを使用して構築しました。基本的なUIはNuxt.jsにて記述し、Google Map を用いた地図操作・レンダリングは別途、JSでクラスを作成しNuxtと連携しました。また、記事の作成の際にはEditor.jsというブロックベースのエディタを採用しました。
デザインは正直得意ではないので、デザインの4原則とブランドカラーを決めてBootstrapをカスタマイズして実装しました。またモーダルなどUIを作るのが面倒だったという理由もあります。
バックエンドは得意なLaravelを使用しました。
フロントではNode.jsを動かせるGoogle App engineを使用しています。理由は後述します。
以降のセッションでは開発に関する細かい内容を解説していきます。
結構長くなるので、重要なことを箇条書きしました。それぞれアンカーを張っていますので気になるとこを見てみてください。
企画、構想では、プロジェクトの基礎となる部分です。頭の中にある曖昧なアイデアや目的を言語化し、はっきりさせることで実際に作りたいサービスがわかってきます。設計を行うことでアイデアを実現させる、ソフトウェア構成を考えようやく開発に至ります。
RouteShareを作成する経緯としては私がサイクリストで、色んなとこにツーリングを行く経験が元になっています。その際、ルートを作るときにGoogle My Mapを使用していました。どんなルートにしようかを考えるとき他人のブログやストリートビューを見たりしていました。しかし、
とルートの共有できるサービスってあんまないのでは?と思う様になりました。
またツーリング友達がルートラボというサービスがなくなり、ルートの共有に困っているということも聞きました。
というサービスが無いかを考えました。ともあれ最初の構想においてはまず自分の体験や、必要だなと思うこと、あるといいなと思うサービスを思うかべたり、既存アプリの欠点を探すといいです。
ちょっと脱線しますが、企画の段階には「アジャイルサムライ」という名著が役に立ちます。チームでのアジャイル開発に関する内容がメインですが、プロジェクトの立案や管理に関する具体的な方法に関してのTipsが多いです。チームだけでなく個人開発でも十分利用できることが書いてあります。ぼっち開発なので第4章の「全体像を捉える」以降が特に役に立ちます。以降の内容でもアジャイルサムライで出てくる内容がちょくちょく出てきます。
個人開発を行うときはアジャイルサムライを購入してみたり、他にも企画やプロジェクト管理に関する著書を買ってみてもいいでしょう。
競合調査をする理由は、
単純なコピーアプリでなく「ユーザーがこのアプリを使うメリット」を出せる様にします。上記で「案外無いんじゃないのかな?」と書きましたが、案外あったりします笑。車輪の再発明にならない様にまず落ち着いて、ググってみます。
RouteShareの場合、まずGoogle Map、Strava、Ride with GPSを調査しました。いくつかのアプリは有料機能の無料期間があったので、サブスク購入して調査しました。また、自分が知らないアプリがあるかもしれないため、「ルート 共有 アプリ」とか「ツーリング おすすめ アプリ」と素人気分になって調べたり、友人に聞き取りをおこないました。
競合調査の結果、一部のアプリには
といった考えていた機能とかぶるとこ、思いつかなかった機能がありました。各種サービスごとに
をリストアップしていきます。「何が足りないか」は「開発に至る経緯」で思った欲しい機能で比較すると良いです。そうすると
などアプリごとの欠点・あった方がいいなと思うとこもありました。既存のサービスを調査したら次は、開発するプロジェクトをはっきりさせていきます。
競合調査を行い意外と被っていたり、何を作ればいいかなどアイデアが曖昧な状態であることが多いです。アジャイルサムライである「全体像を捉える」を行います。特にエレベーターピッチと呼ばれる
以上のテンプレートを使って個人開発で作るプロダクトが具体的になんであり、誰のものなのかということをはっきりさせます。RouteShareでは以下の様になりました。
となりました。自分がサイクリストだったこともあり、ターゲットを限定的にしていましたが「旅行者、ドライバー、ライダー、サイクリスト、街歩き」など「ツーリスト」全体にターゲットを広げました。
他に自分がなぜ旅行が好きなのかを深掘りして、「地域や場所、道の魅力を発信する」という「個人の記録」にとどまらない使い方ができるサービスを作りたいという方向性が定まりました。
大まかなプロダクトの方向性が定まり、次はパッケージリストというものを作ります。これは本の表紙の様なもので、1枚の紙にプロダクトのイメージ図、特徴機能、キャッチコピーを掲載します。ただこの中では特徴機能が重要な気がします。
この「特徴機能」は最初にいくつか候補を挙げておきます。それらの候補から最終的に3つに絞ってパッケージに載せます。しかしここで重要なのは「このプロダクトで何ができるのか」をはっきりさせることです。
この際、アジャイルサムライでは「フィーチャーでなく効能をつたえる」ことを重視しています。フィーチャーとは一言ですむ特徴や機能名のことです。RouteShareの場合、地図機能、記事機能、SNSサービスといった用語が当てはまります。しかしこれらの「特徴」や「機能名」を言ったとこでユーザーからしてみれば、「で、それらは一体何がいいの?」となっていまいます。これらの「特徴」や「機能名」でユーザーの
を具体的に言える様にしましょう。アジャイルサムライでは上記3つのことを「効能」と言っています。RouteShareでは以下の様になりました。
地図にルートの描画、スポットの設置ができる。
地図のルートスポットから記事にリンクをはれる。
地図+記事の投稿を作成できる。
設定したパスやスポットからどこに行ったかのデータを取得される
投稿にタグを貼ることができる。
まずは「〜ができる」「〜する」という特徴を書いたら、「それによってユーザーにとってどう役に立つのか」を箇条書きで書きます。
パッケージは作っても作らなくてもいいですが、作った方がやる気は上がる気がします笑。
方向性が決まり、実装したい機能が定まってきたら選定を行いましょう。RouteShareも開発していくとわかってきた技術的難点やコストの問題で端折った機能がたくさんあります。個人開発ではスコープ管理が自由な分、「こーした方がユーザーにとっていいのでは..」と考えることが多くなります。やること、やらないことを決めないと実装したい機能が後からどんどん湧いて、リリースが先延ばしになってしまい、最終的に途中で頓挫することが多いです。
正直言うとそのサービスが需要があるか、ニーズにマッチしているかは市場に出して使ってみてもらわないと効果測定ができません。後々の設計や技術選定、開発を行いながら「やらないこと(あとでやる)」と「やること」を選定していくといいです。経験的に「やらないこと」に振れないかと第一に考えるとスコープが無限増殖しません。
このサービスでは収益化を考えています。私自身は無料のサービスには限界があり、最終的には何らかの形で有料化・収益化することでより良いサービスになると考えています。使用ユーザーが増えることはその分、サーバスペックも要求されるようになりますし、当初のニーズに対する答え合わせもできるようになってきます。より安定的に、素早くビジネスとサービス品質を加速させるためにはマネタイズは重要になります。
RouteShareも一大プラットフォームになるべく、収益化の構想は考えています。ただし、正直言うとここは自分でも曖昧で「取らぬ狸の皮算用」をしているのでは?と感じているとこがあります。RouteShareでは以下の方法での収益化パターンを考えています。
Google Adsenseなどのサービスを利用して広告を添付します。シンプルで導入はしやすいです。しかし広告添付は収益化のためには非常に多くのユーザーが必要であり、また不安定です。
一部機能に制限をつけ利用したい場合は有料会員としてサブスクを求める方法です。使用しているユーザーや料金、収益状況が把握しやすく収益が安定しやすいです。しかし有料で買いたいほどのニーズの解決や無料枠との差別化が必要であり、収益は単価を多く取るか少なくするかによって必要なユーザー数に依存するようになります。
私は最終的にはこの方法での収益化を目指しています。法人と契約して優先的に掲載できる枠を設けたり、法人のみが使用できる機能を提供、企画を立案してプロモーションを行うことです。サービスにそれなりにユーザーがいて、法人に対してそれなりの利益を提供するまでサービスの成熟と営業が必要なりますが、toCな収益形態よりも安定的で発展性のある収益化形態です。
収益化方法は色々とありますが、少なくともどのように収益を確保するかの構想は初期の設計段階でも考えておくといいです。
いきなり企画の段階でいうのも何ですが、個人の広報力やブランドがない状態でデプロイしても正直ユーザーは来てくれません。個人開発のツイートがバズってたくさん!というのは偶に見ますが非常に稀です。
正直大方のサービスは運営していき、少しずつユーザーを増やしていきます。サービスがいつバズって収益化まで繋がるかは「サービスがどれほどの期間運営しているか」に依存します。下手すると年単位になることもあります。
その時、支出の存在はリリース後の悩みの種になりますのでサーバ代は必ず計算して、いかにケチれるようにすることが重要です。
私の場合Laravelを使用するAPIサーバのためにVPSを新規に借りようとしましたが、計算しても月2000円は追加の出になるため、実は別のブログで運用しているレンタルサーバに導入しています笑
フロントに関してはGoogle App Engineを使用して必要な時に稼働するようにしました。とにかく支出はケチれるようにして、かかる費用は毎月監視するようにしましょう。
ここまではどんな機能を実装しようか、サービスがどうなるのかワクワクしながら進めたと思います。しかし機能を実装するで上にどんなリスクが生じるのかを考えましょう。実際に企画初期段階では以下のように考えていました。
この時さまざまなリスクが思い浮かびますが、そのリスクが「自分が制御できるか」で対応すべきかを決めましょう。例えば「このサービスは受けるだろうか」「ユーザーのニーズをあてているか」は正直考えるだけ無駄なリスクです。なぜなら「その答えはユーザーのみが知っていて、そもそも市場に出さないとわからない」からです。もちろん競合調査などをして可能な限りリスクを下げることが必要ですが、自分がどれほどそのリスクに対して対策を取れるか、制御できるかを念頭にしておくことが大切です。
リスクをよく考えることで早い段階で課題を明らかにでき、プロジェクトが進んでから爆弾が爆発するのを防ぐことができます。あと気持ちがすっきりします笑
プロジェクトの管理はGoogle ドキュメントとスプレッドシートで行いました。企画書などはドキュメントにまとめ、スコープ、実装機能表などをスプレッドシートで管理しました。
個人開発であればJiraやBacklogよりもスプレッドシートぐらいで十分です。チームでも2,3人ぐらいまでなら大丈夫そうです。これらの記録は後で見返したりする時に便利ですし、課題管理はプロジェクトがどれほど進んでいるかの指標になるので作成しておくといいです。
また設計に関しては基本的にスプレッドシート、図などはDiagrams.netを使用しました。
企画・構想が決まったら設計を行います。ここからようやくエンジニアっぽいことをやっていきます。
機能については企画の段階でまとめました。サービスではユーザーが画面上のUIを通じてデータの更新・閲覧を行います。すなわち「どんな画面が表示され、そこで何ができて、どう遷移するのか」を把握します。
いきなり画面図を書くのは大変なので最初はサイトマップというものを作成して「どんなページ(画面)」があれば良いのか?を決定します。webサービスの場合はURLのパスも決めてしましましょう。
サイトマップは名称、パス、タイトル、用途を記述し、認証や特定のミドルウェア的な制御を行う場合は追加で記入しておきます。
サイトマップを作成したらワイヤーフレームを作成します。ワイヤーフレームはページにどんなパーツを表示させ、どんな要素(データなど)を表示するのかを整理することができます。フロント部分で表示する要素を整理することで、実際にどんなテーブル構成にすればいいかを知ることができるようになります。
次はワークフロー図を作成します。ここでいうワークフロー図はプログラム的な処理のフローです。例えばGoogle連携についてのフローは以下のような画像で表現しました。
ER図にてテーブル設計を行います。フロント・バック内でのフローや要素を整理するとER図はすんなりとできることが多いです。
エンジニアで一番大変なのはこのデザインの部分です。ワイヤーフレームをもとにして実際のデザインを作成します。私はAdobe XDを使用して画面ごとのデザイン、UI、パーツを作成しました。ここはFigmaでもXDでも大丈夫ですが、コンポーネントやレイヤー分けできるツールを使用した方がいいです。
デザインセンスがないと感じる場合
以上4点を意識します。
RouteShareはTwitter、Qiita、Stravaを参考にしてそれらを混ぜ込んだ形にしました。よく見ると似ている箇所があります。もちろん完全にパクるのは良くないですが、デザイン・UIの参考として作成した方が、少なくともダサいデザインにはならないと思います。
これを守るだけでなんかいい感じになります。デザインの4原則とは
の4点です。
例えば上記は登録された投稿一覧ですが、
この4点を意識していくと結構いい感じになります。
ブランドを決めます。RouteShareは道路の新型青看板の青色をもとにしています。その色を起点にしてColorHexaなどで輝度方向のパターンの色を使用するといいです。基本的にはブランドカラーはこのようにし決定して、色々とカラフルにしない方がいいです。しかしUIではキャンセル、確認といった箇所では赤・緑・黄色などを使用してしても問題ありません。
デザインとCSS・UI系の工数を省きたい場合はCSSフレームワークを使用した方がいいです。RouteShareはBootstrap-vueを使用しています。フレームワークは好きなものを使用して大丈夫ですが、上記のブランドカラーなどを適用したりプロパティーを変更できるフレームワークを使用した方がいいです。
設計やデザインを作成して技術選定を行います。リリースを重視し、個人開発であればあなたの得意なスタックで大丈夫です。正直いうと、ユーザーにとってみればバックエンドに何を使っていようが、動いていればまずいいのです。あとはあなたの開発効率の問題になります。個人開発ではモチベーションや初版リリースまで辿り着けるかが第一の関門となっています。
そのため技術的な勉強という要素を入れてしまうと、途中で挫折しかねません。もちろん選定したスタックによってはコストがかかってしまうものもあります。しかしその中でもコストと開発難易度がちょうど良くなるスタックを選択した方がいいです。
一番最初のことろはサーバーレス環境で全部おさめてやりたいとも思いましたが、デプロイの設定やFireBaseなどは初めてだったこともありやめました。LaravelとフロントエンドはVue.jsという構成も考えましたが、フロントの構築は1つのフレームワークで行った方が自分的にはかなり楽だったので、LaravelをバックにフロントはNuxt.jsという構成を取りました。
APIサーバとフロントサーバを用意する必要がありましたが、Google App engineの無料枠を利用できる様にしたり、APIサーバーも構成を工夫することで費用を抑えることができました。
1番の悩みの種はGoogle Map APIの課金ですが解決方法は見つけ、まずはリリースを優先するために地図表示はGoogle Mapにまずは任せることにしました。
もし外部サービスのAPIなどを使用する時は規約を読んでおきましょう。公開して、収益を求めるサービスなので規約違反はNGです。
RouteShareの場合はGoogle Map APIで規約違反をしてしまう機能を開発しそうになった時がありました。RouteShareは地図にセットしたラインやスポットを計算して、周辺地図の画像をサムネイルとして設定できる機能があります。↓
このとき当初はGoogle Map static image apiを使用しており、バックエンドで画像のURLにリクエストしてレスポンスの画像をこちらのサーバに置いておくという方法をとっていました。しかしこの方法は規約違反であり、必ずブラウザからstatic image apiのURLを記載することとの規約がありました。
現在は地図サービスのAPIを別途契約して、タイル画像を取得して生成するようにしました。知らぬ間に規約違反することもあるので、規約は難しいですが一読しておくことをお勧めします。
設計、技術選定、デザインがある程度完成したら早速開発を始めましょう。正直のこの開発時期が一番、挫折しやすいと思います。ここでは開発時に大切なことを書いておく程度にします。
個人開発の完成は自身のモチベに依存するため
の気持ちを常に持っていた方がいいです。開発をしている際に一部の設計を見直したり、機能を追加・変更することがあると思いますがスケジュールとスコープがオーバーしないようにしましょう。
私も開発をしている時に「こうした方がいいのでは?」「もっと最適な方法があるのでは?」と思って思うように開発が進まないことがありました。
もちろん期限内に最善を尽くすの良いですが、完璧を求めようとするとズルズルと起源と対応すべきコストが増大します。途中で色々面倒になったり、仕事が忙しくなり放置..ということになります。今の自分が持っている技術スタックの最善を尽くして開発を進めてください。
作り上げることは重要ですが、品質を犠牲にするわけではありません。リリースはゴールではなく、マイルストーンであり経過点です。むしろサービスはリリースしてから始まりますので、リリース後の保守や改善のことも考えなければなりません。
その際に作り上げることを言い訳に自分ですらコードの内容を把握できないものや、保守性の低いものはリリース後のモチベを下げる要員になります。
継続的な開発のために
以上のことはやっておいて損はありません。
あとはもう時間をかけるのみです。個人開発は睡眠時間を削ったり土日を使うことで捻出しました。仕事が終わったら直ぐに個人開発の環境を立ち上げておきます。
まとまった休みにやるよりも、毎日ちょっとずつの方が結果的にリリース達成の確率は上がります。
ここはもう、何とか時間を作ってください。心の中に「リリースまで進み続けるんだ!これはお前が始めた個人開発だろ?」と問いかけるようにしてください。
そしてリリース日やマイルストーンなど明確な目標期限を定めてください。個人開発は管理が自由な分、開発時間などを伸ばしがちです。期限を定めることでダラダラと続けることを防げますし、スコープが増大することも防げます。
開発進み完成してきたらリリースの準備を行います。リリース方法は使用している開発構成によってまちまちですが、基本的にはgitを用いてリリースを管理できるようにしたほうがいです。可能な限り、手動での反映を少なくできるようにした方がいいです。
RouteShareではgithub上でrelease
,test
といったブランチを作成して、本番環境もそれらのブランチからプルするようにしています。フロントエンドはGoogle App engineを使用しており、ビルドからサーバへのデプロイはgithub actionsで自動的に行えるようにしています。
ドメインの設定やSSLなどやることが多いですが、この辺はリリース時に1回で済むので頑張って調べてください。(私もそのうち書きます..)
今後の機能リリースではできる限り本番へのデプロイが楽になるような構成を最初に心掛けた方がいいです。
色々端折ってしまった所がありますが、内容は以上となります。本記事では開発したRouteShareの詳細はお伝えしませんでしたが、また違う記事で機能について開発面で細かく解説した記事でも書こうと思います。ぜひ旅行好きな方はRouteShareを使ってみてください!
デプロイから1ヶ月たち、まだユーザー数やトラフィックも少ないですが今後は運用に注力したり、リリースまでに間に合わなかった機能を実装しようと思います。エンジニアであればこのように製品を自ら開発してビジネスを始めることができます。ディベロッパー的な視点や技術だけでなく、経営や運営、企画の力も付きます。総合的な力をつけたいエンジニアはサービスの大小あれど、色々な人に使ってもらえるアプリケーションを開発してみるといいと思います!