導入
こんにちは!
私は現在北海道のWeb系自社開発企業にてフルスタックエンジニアとして働いていますが、
元々は都内の広告代理店でWebマーケターとして勤務していました。
ですが、趣味で触り始めたプログラミングの楽しさに引きずり込まれて、現在の会社へと転職するに至っています。
今回の記事では、私がエンジニアに転職する時にポートフォリオとして提出したWebサービスの技術スタックや、うまくいったこと・いかなかったことの振り返りを共有させていただくことで、
読者の方の個人開発への知見が広がればいいなと思っております。
サービス概要
下記が今回取り上げるポートフォリオの概要です。
- 正式名称
- 学習院大学 国社生だけのOB・OG相談サイト Kiite-me!(キイテミ)
※以下「Kiite-me!」
- 学習院大学 国社生だけのOB・OG相談サイト Kiite-me!(キイテミ)
- 運営期間
- 2021年3月30日から2022年4月1日まで
- サービス説明
- 一言でいえば、クローズドコミュニティ型Yahoo知恵袋。
- 解決したい課題
- 「Kiite-me!」を立ち上げ始めていた時(2020年8月頃)はコロナの影響で大学生がキャンパスに行くことが出来ず、進路が決まった先輩学生や卒業生にオフラインで就活の相談をする機会が減ってしまっていた。
- 筆者の出身学部(学習院大学 国際社会科学部)が創立して間もない学部であるために、在学時から後輩に「この学部での経験を活かしてどう就活したらいいか」と聞かれることが多かったため、今でも困っている学生が一定数いると感じていた。
- 課題に対する解決手段
- 「Kiite-me!」へのユーザー登録を筆者の出身学部の卒業生と在学生だけに絞ることで、バックグラウンドを共有できている安心感を在学生に感じてもらうことができるようにした
- Wantedlyのような形式で、卒業生の就活体験談をまとめた記事を用意することで、在学生は自分の学部の先輩がどのような就活をしていたか情報収集ができる環境を用意
使った技術と選定理由
実際のサイトは2022年の4月にて運用を終了しているため、
UIやコードは下記のリンク先にてご確認いただければと思います。
※ 実際に使っていたレポジトリからconfigなどの情報を抜き取っているコピーではありますが、一応参考までに...
Webフレームワーク:Django
「Kiite-me!」立ち上げ以前から業務効率化のアプリの作成の際にPythonを使っていたため、
言語はPythonを選び、フレームワークはDjangoを選定しました。
Django以外のフレームワークの選択肢としてFlaskも考えていたのですが、デフォルトで管理画面がついてくる点や、学習リソースの多さからDjangoを選びました。
インフラ:AWS
インフラにはAWSを選びました。
ここでの選択肢としては同じクラウドとしてはAzureやGCPなどがありましたが、
ここでも学習リソースの多さからAWSを選びました。
Webフレームワーク選定時と同様に、私自身ちゃんとしたWebサービスを作るのが初めてだったことや、他の人に使われることを想定したサービスを作るつもりでしたので、
障害時の対応がなるべく容易な技術(=学習リソースが多い)を選ぶようにしていました。
アクセス計測:GA4, UserHeat
前述のように「Kiite-me!」では卒業生の終活体験談をまとめた記事をログイン不要で読めるようにしていたのですが、
どのような内容の記事が読まれているのか、つまり、在学生にとって有用と思われる情報はどんなものか、を探ることで、その後にリリースする記事の内容をブラッシュアップしていくことを目指していました。
そのため、GA4(Google Analytics 4)によって「Kiite-me!」に訪問したユニークユーザー数の計測と、UserHeat(ヒートマップ分析ツール)を用いて各記事ごとの読了率や滞在時間の計測を行いました。
結果的にどの記事が人気で、記事ごとにどんな情報が読み込まれているのか、といったことが可視化され、
記事の方向性の改善を進めていくことが可能となっていきました。
アーキテクチャ:モノリス
実はアーキテクチャに関してはなにも考えずに実装していました...(汗)
当時はレイヤードアーキテクチャやオニオンアーキテクチャなどという言葉の存在も全く知らない状態でしたので、
アンチパターンの筆頭ともいえるようなモノリスプロジェクトとして「Kiite-me!」を作っていました。
ただ、「Kiite-me!」というサービス自体コロナが落ち着けば運営を終了するつもりだったことや、
自分以外の人に実装をお願いするつもりがなかったことから、今回に関してはむしろ大掛かりなアーキテクチャを組む必要はなかった気もします。
以前筆者が書いたアーキテクチャに関しての記事でも説明しているように、アーキテクチャの意義は 保守性 と 拡張性 の担保であると私は感じています。
そのため、どの関数がどこにあって影響範囲がどこまでなのか、というのが自分の頭の中にあって、
ターゲットのユーザーの数も筆者の出身大学の在学生と卒業生に絞られている、という状況で、スケールすることや高負荷の環境を考慮しなくてよかったため、アーキテクチャはアンチパターンとされるようなモノリス構成でもよかったのかな、と考えます。
実装が難しかったところ
利用規約の作成
厳密には「実装」ではないですが、サービス開始にあたり若干の手間を取られたのが利用規約、およびプライバシーポリシーの作成でした。
曲がりなりにも「Web上のサービス」として、メールアドレスなどの個人情報を預かる必要があったので、安心して利用してもらえるように作成を進めました。
作成の際は、「Webサイトの利用規約」というページにていくつかひな形を入手し、
複数のひな形を見比べながら必要な箇所を編集、追記しました。
プロフィール画像のトリミング
SNSには欠かせないプロフィール画像のトリミングの機能ですが、やろうとすると色んなライブラリを急にたくさん入れなくてはならなかったので仕組みの理解に時間がかかりました。
ただ、画像のトリミングを行うにはJS側でのAJAXの実装も必要でしたし、Django側での画像の処理の実装も必要だったので、ここらへんの知識についてはかなり勉強になりました。
参考:Cropping an Image using Javascript and Python
その他苦労した点、そしてどう乗り越えたか
質問数が少ない
「Kiite-me!」を1年間運営して集まった質問の数は最終的に「12件」でした。
ターゲットとしていた学生の人数が500人弱だったことから、ターゲットの内の2%が利用してくれたと考えれば数としては少なくない気もしていたのですが、
私が在学中に後輩学生向けの就活相談イベントに参加したときに受けた質問のボリュームと比べると「もう少し質問が集まってもいいのでは?」という感覚もありました。
質問が少なかった要因として考えたのは、Yahoo!知恵袋と同じように投稿した質問を他のユーザーも閲覧可能にしていたために、「パーソナルな質問」を見られるのが恥ずかしいと思っている可能性が挙げられました。
実際に知り合いの在学生にアンケートをとってみたところ、「悩んでいることを友達や知り合いに見られるのが恥ずかしい」などの意見が見受けられたことから、改善の余地があると感じました。
元々の思想としては、誰かの質問を他の在学生も見れるようにすることで、知識の共有や意見の交換が簡単にできることを狙っていたのですが、
「同級生に自分の悩みを見られるのが恥ずかしい」というマインドの方が強かったようです。
最終的に質問を投稿する際には下記の2つの設定を行えるように変更しました。
- 質問を他の在学生に見られないようにできる設定
- ユーザー名を伏せて匿名で質問できる設定(質問自体は他の在学生も閲覧可能)
元々のユーザーのアンケートから考えれば 1.の機能だけ追加すれば良いとも思いましたが、
質問をしづらいと感じるさらなる要因の一つとして「回答してくれる卒業生に対しても自らのプロフィールが知られるのが嫌」という人もいるのではないかと感じたため、2.の機能も追加しました。
上記の変更点の実装後には、それまで質問を1回もしたことのなかったユーザーが匿名機能を使って質問を投げてくれるようになったので、一定の効果はあったのではないかな、と感じています。
卒業生のレスポンスが遅い
在学生が質問をしてくれるようになっても、答えてくれる卒業生のレスポンスが遅くてはWebサービスとしては力を発揮してくれません。
「Kiite-me!」がモバイルアプリであればスマホへのプッシュ通知も可能となり、卒業生も反応しやすくなると思うのですが、
Webアプリケーションとして運用していたため、通知をメールに頼らざるをえなかったため、卒業生ユーザーから「質問に気づけない」という声が届いていました。
サービスローンチ直後の段階では「Kiite-me!」内にユーザー向けの、いわゆるお知らせ一覧ページのようなものが何もなかったので、「メールは見ないけどKiite-me!のサイトは定期的に開いている」という卒業生が自分宛ての質問が届いていても気づかない作りとなってしまっていました。
そこで対策として、マイページが用意されているSNSには必ずあるようなお知らせページとナビゲーションバーでの通知用ベルマークを新しく用意しました。
ただこちらでは実際に効果を感じられず...汗
最終的に「LINEで通知が来たらさすがに気づくだろう」と思ったので、「kiite-me!」のLINEの公式アカウントを作成し、SDKを利用して質問が投稿されたらLINE経由で卒業生に通知が届くようにしました。
結果的にはこのLINE通知がかなり効果的で、元々卒業生の回答に1週間ほどかかっていたところから、翌日には1つめの回答がつくところまで改善されました。
ただ、やっぱりブラウザ版のアプリケーションだとユーザーへの通知に工夫が必要なんだな、というのが思い知らされました...
今から作り直すならどこを変えるか
ログ監視ツールの導入
大きな障害はなかったと書きましたが、気づいていなかっただけで裏で起こっていたという可能性は十分にあると思います。
実は知らない間にAWSのインスタンスが落ちていたということも2,3回ほど発生していました。(全て運よく3,4時間以内にたまたま気づくことが出来たので大事には至らなかったですが...)
CI/CDのパイプラインの構築
上記のログ監視ツールを入れるのであればこちらもほしかったところです。
実際に、ローカル環境で動いていた(ように見えた)コードを本番環境に反映して、本番環境での確認中にバグを見つけたことも何回かあったので、それを防ぐためにも最低でもCI時に動く単体テストくらいは作るべきでした。
フロントをリッチにする
「kiite-me!」のターゲットが学生で、日ごろからイケてるアプリになれている層であったため、ここは本来もっとこだわる部分だったな、と反省しています...
最終的にはBootstrap3を基本に、登録時の必須項目の表示の切り替えなどの必要最低限な箇所にだけjQueryを加える書き方をしており、正直全体的なUI/UXとしては及第点に届かないような作りだったと感じているので、
今から作り直せるのであれば、別のJSのライブラリを使って少ないコード量でイケてるUI/UXを実現できるようにしてみたいなと考えています。
共通した処理のライブラリ化
ありがちなDRY原則の話になりますが、結構大事な部分です。
例にもれず「Kiite-me!」においても、質問の投稿や回答をする時の入り口がいくつかあり、その入り口ごとに処理を書き分けてしまうというアンチパターンを突っ走ってしまいました。
アーキテクチャの勉強をいくらかした今であれば、こういった場合ほど実際の処理をDjangoのviewsとは別のところに書いておいて、
viewsでは抽象化されたメソッドを呼び出すだけ、という形にすることで、DRYを守る書き方にできればよかったと感じています。
まとめ
今回の記事では私が未経験の状態から現在の会社にエンジニアとして転職する時に使用していたWebサービスの紹介をさせていただきました。
自分はポートフォリオとしてWebサービスを作るのであれば、実際に誰かの生活をよりよく出来るようなものが作りたいと考え、この「Kiite-me!」を作りました。
(むしろ誰にも使われないアプリケーションをポートフォリオとして作ることに一向にモチベーションが湧かなかったのでなんとかしてこのアイデアをひねり出した、という方がより正確ですが...汗)
ただ、実際にユーザーがいるサービスの開発・運用を行ったことで、「サイトが落ちたら全部自分の責任」というエンジニアとしての怖さや、「自分の母校の学生の力になれた」というやりがいや楽しさといった部分を大いに経験できました。
また、こういった個人開発を通してでないとインフラからフロントまでのWebサイトの全容を知る機会もなかったので、こちらも良い経験ができたと感じています。