こんにちはカレイドです。
先日初めてのWebアプリのリリースをしました。丁度現在このブログを執筆段階の2019/06/06 お昼12時ですが
RT42件、いいね数182件頂いています。たくさんの閲覧ありがとうございます。
https://t.co/RZmhzd7cOd
ついに完成しました。プログラミング学習から2月から本格的に始めて、120日ぐらいでオリジナルアプリまで作成できました!制作期間は14日間
皆で習慣を共有、可視化して継続力を高めていくアプリです!感想などはDMかリプでくれると助かります。どんなものでも大歓迎です!— カレイド@4ヶ月で自作アプリまでリリース (@kaleidoblog) June 5, 2019
今回はさすがにツイートだけでは全部書ききれなかったのでアプリ開発の経緯から開発期間14日間の流れについて
少しずつ話していこうかなと思います。かなり長くなるのでここではManehabiの概要や背景苦労したことに留めて初心者さん向けの言語の選び方などはまた別記事でまとめます。
これからWebアプリを作ろうかなと思っている方はぜひ読んで頂ければと思います。
なぜManehabiを作ろうと思ったのか
まずはこのアプリケーション作った目的から話していこうと思います。
まずは、アプリを作って実践経験を積むことが大事だと考えています。インプットばかりでは自分がどれだけ努力しているのかは皆さんに報告が出来ないと思ってとりあえず何かしらデプロイしようと考えました。
作った背景について
本格的に勉強を始めようと思ったときからTwitterを情報収集のために活用して、このTwitterから発想を得ました。
ビジネスの勉強のために、参考になる人は一気に努力して継続しているイメージが強かったです。
自分は結構飽き性というのもあってプログラミングもまた飽きるんじゃないかなと思っていました。そこで習慣に関するアプリ作れたらいいかもしれないってふわっと浮かんできました。
なぜ習慣をトピックにしたのか
私が参考にしているというか理系気質なのもあってメンタリストのDAIGOさんはよく参考にさせてもらってます。論文ベースなので説得力もしっかりしているのが魅力ですね。
そのDAIGOさんが習慣の継続方法はとにかく小さく、積み上げが大事ってことを言っていました。
ここでいう積み上げっていうのは目に見えて成長しているという証のことです。人間成果が出ないときは本当にこれでいいのか、道がぼやけていて習慣が途切れやすいタイミングになります。
受験時代の勉強ってよくRPGだったらもっと自分できたんじゃないかなっていう人いるんじゃないかなと思います。
というわけで時間という経験値をためるアプリは世の中にあるわけですが、それを共有しているアプリって軽く調べたところ一切ありませんでした。
なので発想も面白そうだと思ったので割と迷わず作ることを決めました。
おすすめポイント
といってもコンセプト以外は割と誰でも思いつく部分なのであまりありませんが、
Daigoさんが重要と言ってた部分はかなり取り入れてます。
なんでも積み重ねる。ってとこですね。このアプリでは挫折回数ですら積み重ねて何度でも這い上がれるようにしています。
現状では今は継続をリセットするボタンを押すと継続日数がリセットされて挫折回数が1増えるようになっています。
次回アップデートでこのボタンは挫折から立ち直るボタンにでもしようかと思います。笑
使う言語やDB(データベース)の選択について
初心者向けの言語の選択についてはまた別記事で話すのでここでは私がなぜその構成にしたのかについてまとめておこうと思います。
選ばれたのは React+Node.js+Express+MongoDBのMERNスタック+GraphQL
一言でいうなら私が参考にさせていただいている就職先の社員さんがNode.jsとReactを使っていたのが一番大きな要因になります。
現在日本での主流はLAMP
- OS:Linux
- Webサーバー:Apache HTTP Server
- データベース:MySQL
- プログラミング言語:PHP/Perl/Python
言語はおそらくPHPが一番多いのかな?だと思いますが、
私の就職先ではPHPは使っておらずRubyなども下火で使っていないそうです。
webアプリ主流のこの二つを使っていなかったので何を使ってるのかなーと思ったらpython+flaskやNode.jsを使っていることを聞いたのでいろいろ自分なりに調べたら今はMEANスタックが徐々に伸ばしてきている
ということを学びました。
私は就活が終わっていてあくまで目標は稼ぐ力を身に着けるのもそうでしたが即戦力になることだったのでPHPではなくNode.jsを社員さんがつかっているということで選択しました。
フレームワークにはVue.js Angular Reactなどありますがこの時はJavaScriptに一切精通していなかったので社員さんがおすすめということでReactを選びました。
そしてDBには今流行りのMongoDBを選択しました。
そしてGraphQLですが2019のトレンドで私が就職するころには結構はやってきているんじゃないかなってことで先に取り入れることを決めました。
あくまでMongoDBオンリーでも組めますが個人的に処理の仕方が好きだったので間違いなく使った方がいいと思って取り入れています。
アプリ制作の流れ
アプリの制作に正解の手順はないと思うので一例ということで考えてもらえればと思います。
step.1 create-react-appで最初のclient画面の設計
私はまずはフロントから始めることでイメージわかせてこれから作るんだぞって気分にしてました。
簡単にルーティングをして自分が大体思い描いたページ構成のナビゲーションバーを作り上げます。HomePageも何となく作り上げておきます。
step.2 認証のフロント部分の設計
私が今までいろんなアプリの設計をしていく中で大体ログイン画面を完成させておくとスムーズに開発が進んでいるのと、割と何度も実装しているので自信がありました。
そこでまずはフロントの認証部分を作成してデータ入力等が出来るようにしました。
step.3 バックエンドとフロントエンドの接続
ここでNode.jsとReactのデータの受け渡しのために接続を行います。
今回はNoSQLのMongoDBを使ってデータの保存です。取り出したデータをGraphQLを使って必要な分だけ取り出せる形にしています。
ログインログアウトができるだけで一気にWebアプリ感が出てきます。笑
step.4 新しい習慣の作成と表示
ここからメインテーマのCRUD作りが始まります。
CRUDはそれぞれの英単語の頭文字をとったもので
C(Create) R(Read) U(Update) D(Delete)。
になります。これはWebアプリ作成の基本になっていてどのアプリもこの拡張になるのでUdemyの講座でひたすら復習していたのは大きなメリットになりました。
難しいものはそのロジックが多少複雑になっていますが基本的なイメージ図が変わることはなかったので割とスムーズにできたんじゃないかと思います。
step.5 習慣の更新、削除
続きになりますが、更新と削除はちょっと複雑で僕のアプリでは習慣の更新はその日に積み上げたぶんの更新なので習慣のモデルとRecordというモデル二つに紐づける必要があります。
同様にして削除をする場合もその習慣を削除するだけではなく、私のアプリではお気に入り機能もくっついているので、その習慣をお気に入りに入れているユーザーからその習慣を取り出して削除するという作業も
含まれることになります。なので更新と削除は前二つに比べて少し難易度が高かったです。
step.6 習慣の記録を取り出してグラフに表示
これが一番難易度が高かったですね、この機能が一番重要なのに最後に回したぐらいとっかかりが難しかったです。ここは苦労した部分で詳しくお話ししますね!
step.7 メディアクエリーの設定とレイアウトの調整
大まかな機能が出来たところでレイアウトとメディアによって表示方法の変更を加えています。フロントのフレームワークにsemantic-uiを使っているのである程度はやってくれていますが
細かい部分などは調べながらちょっとずつstyleの変更を加えていきました。
思った以上にデザイン好評だったのでフレームワークってやっぱすげえなって思いました。
Webアプリを作りたい人は中のロジックを頑張って表のデザインはやっぱりある程度フレームワークに頼るのが一番賢いと思います。
全部やろうとすると間違いなくパンクするのでお勧めしません。
step.8 Herokuのデプロイ
ここも挫折ポイントでした。正直何度もUdemyで経験していたので、今更失敗することなんてないだろうと思っていましたが、フロントとバックのセットのデプロイだったのもあって結構はまりました。
これ解決するだけで1日半かかってしまい予定とずれる一番大きなポイントになってしまいました笑
これも苦労した部分で話します。
苦労した部分
では実際に苦労した部分について語っていこうと思います。前の段落にも書いた二つとあともう一つあります。
① データベースからデータを取り出してグラフに表示する
データベースにはユーザーが更新されたときにしかデータが保存されないので
実際のユーザーが毎日習慣を更新してくれていればいいのですが、そうでない場合には足りない日のデータを補う必要があります。このロジックを考える部分については
【プログラミング】アルゴリズムの考え方を実際の例題付きで解説するよ!
で詳しく解説しています。私自身まだ複雑なロジックに当たったことないので愚直に解いているのでもっと楽な方法ある場合には教えていただけると幸いです。
もう一つは単純にサーバーからデータを取り出すときに日付を扱うのですが、今までたくさんアプリ触っても複雑な日付を扱うことはあまりなかったので比較や一致など
moment ライブラリを扱うのに苦労しました。自分でググりながら調べたり、console.log()で確認したり、型タイプでタイプを調べることなんてないと思ってましたが初めて役に立ちました。笑
でもこれでかなり日付の扱いについては慣れたんじゃないかなと思います。
② Herokuへのデプロイ
意外や意外、udemyのアプリ制作で5,6回は経験していたのではまることはないと思っていたのにはまってしまいました。
原因はまず僕はGraphQLをデータ取り出しに使っているのですがどうやらUdemyで見た時とアプデが入った関係でversionが異なっていたらしく大幅な変更が加えられていました。
また、Reactではデプロイ時にはbuildフォルダと呼ばれる圧縮されたフォルダが作成されるのでdevelopmentの時とproductionの時でルーティングが異なります。
ここまではよかったのですが原因がうまく掴めず最終的な原因はexpressをうまく理解しておらずルーティングをうまくさばけていないことが原因でした。
実際解決したのはstackoverflowと呼ばれるプログラミングの海外の質問掲示板を利用させていただきました。
解答してくださったかたの答えをそのまま適用しようとしたらうまく行かなかったのですがそれが解決の糸口になりました。
③ MongoDBの複雑なクエリーとソート
Udemyの講座で何度か使っていますが自分が取り出したいようなクエリーピンポイントで勉強することはないのでうまくグーグル様を使ってその都度解決していきました。
mongodbを便利に使うmongooseと呼ばれるライブラリがあるのですが、最新バージョンと前のバージョンで異なることもあるので技術者としてこういう部分は気を付けていきたいなと思ってます。
またあとで実装予定のお気に入りの表示についてですがこれがかなりいい例になると思います。現状まだ組めていないのですが、以下の図のように
Userモデルにはユーザーがお気に入り登録をした習慣のIdが配列で保管されています。そしてそのIdの習慣はそれぞれその習慣作った人を記録しているcreatorと呼ばれるデータを保存しています。
私のアプリではそのユーザー名が必要なためネストが二段階になっています。
このような複雑なクエリーは扱ったことがないので実装見送ってます泣
DBのクエリーはまだまだ初心者なのでソートや条件分岐なども含めて今後の課題になりそうです
機能の解説
ここでは現状のアプリ出来ることをまとめておきます。
- ユーザー登録(JWT認証機能)
- 新しい習慣の登録
- 習慣の更新(その日の積み上げを記入してグラフ化) 同時に継続日数が1加算され、更新日がその日になります。
- 習慣の削除
- 挫折したけど改めてリセットボタン(習慣から離れていた場合新たにリセットボタンで新しく習慣を始めることが出来ます。今までの積み上げリセットされません)挫折回数+1
- 習慣のお気に入り登録(表示はまだできない。笑)
- データのグラフ化(7日間、28日間、90日間選択可能)
割と最低限のCRUD機能とグラフ表示化ですね。
今後の予定(実装予定の機能)
めちゃくちゃたくさんあるのでひたすら記述していきますね。
- トークンの有効期限が切れたら自動ログアウト(出来るか不明)
- お気に入りの表示(ユーザーお気に入り画面の実装)
- お気に入りからユーザーページへ飛びそのユーザの習慣を表示
- 自分のプロフィールの設定。一言機能やアバター変更
- 任意の個数の習慣のユニット管理
- 習慣のタイトル内容の変更機能
- 習慣に一言コメントを残せるように実装(他のユーザーからの一言もかける)
- Twitterログイン
- データの可視化の28日間90日間の見栄えがすこぶる悪いので改善
- 同時にカレンダーの設置と任意の期間のデータ表示
- 検索機能(スター数、作成日、挫折回数、継続日数、更新日、タイトル検索、説明検索)
- 挫折回数の更新は1日1回のみに変更(更新日がその日は不可)
- 各画面でデータ送信後正常処理ならメッセージを簡易的に表示
- ランキング機能
- ローダーをかっこよく
- よくあるタグ付けをできるように
果たしてすべて実装するまでどのくらいかかるのかわかりませんが出来るところまで頑張ろうと思います....
デプロイまでして感じたこと(疑問点)
例えば加えたい機能があったときにデータベースのモデルに付け加えるというよりは大幅な変更が出来てしまったときはどうするのか、
例えば今回なら現在の習慣は時間と何かもう一つで管理という形になっているので、それに対応したモデルにしているのですが、
3つ、4つと単位が増えるならそのレコードに単一のIDを付与してまとめて管理した方が効率がいいかなと思っています。
そうなってしまった場合にはデータベースが大幅に変わり現在使っているユーザーのデータ移行なんかは実際の現場ではどのような形にしているのかすごい疑問になります。
もしくはそもそもそういうことが起こらないような設計にするのがベストだとは思いますが、仕様上このようなことが起こらないとは限らないと思うのでどのような解決策を取っているのかとても気になりました。
これからWebアプリやMobileアプリを作ろうと思っている方へ
まずは何でもいいからデプロイまで漕ぎつけましょう!
メモアプリに少し一工夫したものでも一から作れればいいと思います。
最低でもCRUD機能は必須で、何かIアイディアあれば十分一つのアプリとして成り立つと思います。
デプロイしてツイッターで報告すればみんなあったかいのでそれがすごい励みになってまた勉強の意欲が湧くようになります。
おすすめはとりあえず実装しながら壁に当たったらまずはグーグル検索無理そうならいったん飛ばして他の機能を実装。
また帰ってきて再度試みてだめなら質問という形が一番実力つくかなーと思います。
まとめ
今回はWebアプリManehabiの機能の説明や背景など、自分が考えていたことを全部まとめてみました。
本気で勉強して本気で出したので燃え尽きるかなと思いましたが、付け加えたい機能が山ほどあるので全く燃え尽きていないのが現状です。
たぶん全部の機能を付け加えるときには次作ろうと思っているアプリが既にあるのでよりよい構成になるかなと思ってます。
実際私がReactに注目して勉強したのは3か月なので最初から道が決まっている人はさらに早くリリース出来るんじゃないでしょうか。
これから勉強を始める方、今挫折しそうな方の手助けに少しでもつながれば幸いです。