🦔

【挫折経験アリ】プログラミング未経験から独学10カ月でAWS,Laravel,Nuxt.js製webサービスをリリースするまで

2021/01/02に公開

プログラミング初心者こそ個人サービス作るべき

本記事は、Qiitaからの転載です。
https://qiita.com/43z708/items/b56a4f30e337c708e387
一度プログラミング学習に挫折したこともある僕ですが、学習を再度開始して半年ほど経ってから個人開発を始めました。

まず前提ですが、この記事は以下の方向けです。

- プログラミング頑張りたい初心者
- プログラミング学習継続してるのに中々成果が出ない方
- 個人開発でアプリケーションつくりたいから参考にしたい方

少しでも、プログラミング初学者の方の学習継続のヒントになれば幸いです。

まず初めに、一念発起して本気で個人開発したwebアプリがこちらです。

https://connectee.jp/

サービスの目的は3つあります。(12/31改定)
1. オンラインイベントの開催にかかる負担を減らす。
2. オンラインイベントの収益化をサポートする。
3. SNSを有効活用したオンラインイベントが運営できるようにする。

まだまだ機能的に足りていませんが、サービスが目指す世界は以上の3つです。

サービスの構成

connectee-Diagram.jpg

ご覧のとおりの構成ですが、構成を決めた理由を以下に記していきます。

バックエンド

![connectee-Diagram.jpg]https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520231/87a9a0b7-704d-c187-34e4-48b58c7751fe.png
プログラミング始めてからの半年ほどはWordPressガチ勢でオリジナルテーマ開発とかやってたので、PHPで行こうと思い、Laravelを選択。
これは選択というより前提という感じでした。

フロントエンド

SPAで開発したい!と思ったので、Laravel内のvueで作ろうかと思ったのですが、イベント紹介ページなどはSEOが重要なので、SSR対応は必須です。
そのためNuxt.jsを選択しました。

インフラ




文献の豊富さからAWSにしました。割とポートフォリオだとHeroku使われるようですが、個人開発バンバンやっていきたいし、一人で全部できるエンジニアになりたかったので、インフラにも力を入れるため、Herokuなどは使いませんでした。
最初はふつうにEC2内にDocker入れて、、、と思ったんですが、拡張性、障害時の復旧、CI/CDとの相性など、評判の良いFargateを採用することに決めました。
また、割と頻繁にアップデートするだろうし、デプロイは自動化しておきたかったので、codepipelineを採用、AWSの管理画面で練習しているうちにごちゃごちゃしてくるし、別のサービスが入ったらどれがどれかがわかりにくくなるな、と思ったので、コードで管理できるcloud formationを使うようになりました。

初めてのプログラミング学習は挫折

もともとはしがない塾講師です。
そんな僕がこのままではマズイ!と行動を起こしたのはAIが流行り出した2017年ごろ。

このまま塾講師やってたら仕事がなくなる、、、、
と不安に駆られ、ITに関心を持ち始め、何かwebサービスやりたいと思うようになりました。

プログラミングを自分で勉強して作るのは途方もないな、と思い、社内事業としてサービスを外注しながらスタートすることにしました。
このときの僕は、自分一人でやっていこうという覚悟もなければ、スキルもない、お金もない、会社に頼り切るしかない状態でした。
そんな情けない自分なのに、意気込みと努力は注ぎ込んでいたので、数年後に失敗する姿など微塵も想像していなかったのでした、、、恥

そして、サービスを主導するリーダーのポジションをやるにあたり、マーケティングや事業運営、新規事業開発のやり方を勉強する合間を縫って、
自分でも少しは理解したほうがいいだろうということで、progateをやってみたのが最初のプログラミング学習。
HTMLはなんとなくわかり、JavaScriptあたりで忙しさと面倒臭さでいつの間にかやらなくなっていたのでした、、、

これがはじめてのプログラミング学習の挫折でした。

プログラミングを本気でやろうという覚悟が全然できていなかったことが最大の失敗要因だと思います。

プログラミング学習再チャレンジのきっかけ

それから月日は流れ、前述のとおり、結果的にプロジェクトは失敗に終わりました。

このサービスの失敗の要因は様々あるのですが、最大の要因は自分が作れないことだと考えました。
自分で作れないからお金がかかる、正確な工数やイメージ通りのサービスになりにくい、、、
など、考えました。
とにかく会社や人に頼らないと何もできない自分に腹が立ち、自分でできる力をつけないとダメだ!!と強く思いました。

もう失敗を経て精神的に追い詰められきっていたので、なんというか生存本能というと大袈裟かもしれませんが、完全にスイッチが入った感じがしました。

目標は会社に頼らず個人で生きていける力をつけること、でした。
このとき本気でやるぞ!と強く心に誓ったことが、学習を継続できた要因の最初の一つだと思います。

プログラミング学習教材とかけたコスト

後ほど、めちゃくちゃよかった本はちょこちょこご紹介します。

- ドットインストール(無料のみ)
- Progate(1か月のみ、1000円)
- 10~15冊くらいの本(全部で3万円ほど)
- Qiita

だいたいこんな感じだったと思います。
基本的に本とGoogleがメインでして、
プログラミングスクールは頭をよぎることすらなかったです。
むしろランサーズとかで案件すぐ取ってたので、すぐにプラス出せて良かったです。

最初はhtml、css、JavaScriptをprogateとドットインストールで

ここからは限界まで睡眠時間を削ってひたすら勉強です。
1週間ほどでHTMLとCSS、JavaScriptの基礎くらいまでをドットインストールとprogateを交互にやりました。
意識したのは実際に自分でもコーディングすることでした。

ランサーズでランディングページ案件を初受注して勢いをつける

勉強を開始してからまだ1~2週間ほどですが、このタイミングでランディングページの案件獲得に挑戦しました。

まだ早いだろ!と躊躇する方も多いと思いますが、僕はぶっ込みました笑

というのも、ランサーズにはコンペ形式の募集案件があります。
これは、応募者がデザインカンプを制作して、発注者は応募があった制作物から選び、選ばれた応募者が正式に作業して納品する、という形式です。
この形式だと、ある程度発注者と受注者との間ですり合わせがされた状態からのスタートになるため、発注者にとってのハズレを引くリスクが少なく、受注初心者にとっても自分が対応できる完成予定物を事前に提示できるためリスクが少なくなります。

僕の場合、ランディングページ制作に必要なイラレやフォトショ、XDなどの最低限のスキルはあったので、それほど苦労せず案件獲得することができました。

この早すぎるタイミングでの受注が結果的に学習のモチベーションを上げる最大の要因だったと思います。

勉強したことがお金になる瞬間を経験することで、もっと勉強したらもっと単価上がる!無駄にならない!とわかるので、難しいと感じても頑張れます。
こうして学習のスピードをさらに上げたのでした。

次はPHPとWordpressの勉強をしながらWordpressオリジナルテーマ開発

[このWordpressの過程は、最初からWeb開発で転職目指す方などにはムダな過程だと思います。]

プログラミングを始めてから1ヶ月が経つ頃にはPHPとWordpressのprogateとドットインストールが完了して、wordpressのオリジナルテーマ開発を始めていました。
初めは、本などに載っているテーマを模倣し、そのソースを参考にしつつ、自分が思う機能を盛り込んだものを作っていく、というやり方です。

今から思えばいわゆるコンポーネント志向で、
案件ごとに使い回しが効く自分専用テーマみたいなものを作っていきました。
案件受注するたびに既存のテーマなどをいじって納品する、という人もいるみたいですが、

  • 自分の血肉にならないこと
  • 細かい調整が入ったときに対応しづらいこと
    の2点から、自分がゼロから理解しているフレームワーク的なものを作りました。

wordpressの情報はネットで溢れかえっているので、ある程度の機能は自分でも作れるし、この経験でPHPの理解が進んだと思います。

半年ほどweb制作に没頭

wordpressのオリジナルテーマができてからは、それを使ってコーポレートサイト、サービスサイト、ECサイトの構築を行っていました。
しかし、労力のわりに報酬が少ないweb制作1本でいくわけにもいかないので、いよいよLaravelの勉強を開始しました。

Laravelの勉強を2週間で

本での勉強
https://www.amazon.co.jp/dp/B08625YD7H

ネットでチュートリアル
https://www.hypertextcandy.com/laravel-tutorial-introduction

をやりながら隙間時間でsqlの勉強も併せて行いました。

webサービスを構想

そんな中、コロナの猛威もあり、オフラインがすべてできなくなったことにより、オンラインイベントが成長していました。
この時点では、まだオンラインイベントの開催がやりやすいプラットフォームがなかったことから、
ポートフォリオがてら、webサービスを作ってみようと決心しました。

まずはサービス設計

1.サービスの軸を決める

  • ZoomのAPIを使って開催の手間を減らしたい
  • SNSでイベント開催の呼びかけをするものの、なかなか反応がない、集まらないという課題感の解決

と考えました。

2.顧客を想定して機能の洗い出し

オンラインイベントプラットフォームを作るということは、マッチング型なので、
開催者と参加者の両方を集める必要があります。
どちらを優先するかというと、これはほぼ間違いなく開催者を優先すべきなので、
開催者ファーストでサービス設計を落とし込んで、機能を洗い出していきました。

3. 画面設計

Adobe XD を使い、サービスのイメージを具現化する作業です。
CRUDに基づいて抜けがないように配慮しつつ頭の中のイメージを書き起こしていきました。
この過程で、非同期に画面遷移ができるSPA(シングルページアプリケーション)にしよう、と決断しました。

4.テーブル設計

事前にリレーションの考え方や、正規化を勉強し、サンプルを複数見て、自分のサービスの設計を行いました。
https://engineers.weddingpark.co.jp/?p=662
このサイトが勉強になったことが印象強いです。

5.フロントエンド側の技術選定

SPAだと、動的に画面が変わるため、SEOに弱いという欠点があります。
本サービスでは、SPAにしつつ、イベントサイトなのでSEOも重視しなければならないため、SSR対応は必須でした。
そのため、カンタンにSSR対応ができるNuxt.jsを選定しました。

いよいよ開発スタート

バックエンド開発から

まずはバックエンドのLaravel側でAPIサーバーを開発していきました。
リレーショナルデータベースの場合、sqlで部分一致検索は重たいことを学び、その解決策として、「全文検索」という技術が使われていることを知りました。検索には力を入れるべきサービスなので、AlgoriaというサービスのAPIを導入しました。
また、イベントを開催するグループごとに決済権限を持たせたかったので、stripe connectの導入をすること、
それからオンラインイベントなのでメインとなるZoomAPI連携を実装する必要がありました。
特にstripe connectのAPIやZoomのAPIはドキュメントがすべて英語で、日本語の文献もほぼない状態だったので、このAPIを使うところが最も苦労したところです。
だいたいバックエンド開発に1か月ほどかかったように思います。

開発環境の変更

また、開発環境として、それまでvagrantを使っていたのですが、遅すぎるし、環境要因のバグなども嫌だし、何せ遅いし、確実に使われなくなる技術だし、とにかく遅いので、Dockerでの環境構築のお勉強も隙間を縫って進めていたので、遅ればせながらdocker-composeで開発環境を構築しました。

フロントエンド開発へ

ある程度APIエンドポイントが出来たら、Nuxt.jsでのフロントエンド開発に移行しました。
PHPほどはjavascriptに慣れていなかったので、1.5カ月ほどかけてフロントエンドの実装を行いました。

特に苦労したのは、オンラインイベント中に使うチャット機能の実装でした。リアルタイムに通信を行うため、FireStoreを利用することにしました。websocketを使う手もあったのですが、APIサーバーの負担を減らしたかったため一定まで無料利用できるFirebaseを選択しました。

また、web版のプッシュ通知をOneSignalのAPIで実装するのに併せてPWA化も行いました。ただ、NUXT.JS自体が簡単にPWA化できるので、この点は一切苦労しませんでした。

難しいイメージがつきまとうインフラ、AWSへの挑戦

ある程度できてきたら、いよいよ恐怖のインフラです。

AWSの勉強をする以前に、そもそもネットワークの基礎が理解できていなかったのですが、
この本はネットワークの基礎から書いてくれているので、とてもよかったです。
https://www.amazon.co.jp/dp/4296105442

他にも動画や本で勉強しつつも、結局自分で動かさないと身につかないので、
実際にAWSを動かして理解を深めていきました。

いろいろと勉強していく中で、ECS、kubernetesの存在を知り、この技術を使うことで、オートスケール、障害時の対応、環境依存をほぼなくせる、CI/CDとの相性など、総合的にメリットが多いことを知り、fargateでの環境構築を実際に管理画面からポチポチやってみることから始めました。

なんとか苦戦しながらも本番環境用のDockerfileをイチから書き直してfargateに乗っけることに成功し、

機能追加などをどんどんやるのに、デプロイの作業がとても面倒だったので、CI/CDツールの導入を検討しました。
CircleCIが有名どころですが、
管理上、AWS一本で統一しておきたかったため、Codepipelineで、GitHubのブランチにgit push するだけでデプロイするフローを作りました。

さて、いろいろやっているうちに、AWSの管理画面での運用がやりづらいな、、と思うようになっていました。

というのも、一つのサービスでさえ、セキュリティグループなどゴチャゴチャしてくるので、複数サービスローンチしたら余計わかりにくいだろうな、、と思いました。

そこで、infrastructure as codeを導入することにしました。

こちらも、Terraformが有名どころかとは思いますが、
同じく管理上、AWS一本で統一しておきたかったため、Cloudformationを採用しました。

いよいよ、デプロイ、ベータ版リリース!!と思ったらZoomの審査が厳しすぎた、、

リリースには欠かせないZoomのAPIですが、
JWTで認証してAPIを利用するパターンと、OAuthで認証してAPIを利用するパターンがあります。

JWTだと社内利用などクローズドなシーンで使うことができるのですが、
今回はwebサービスとして不特定多数の方に公開するため、OAuthでの認証は欠かせません。

申請に必要な事項を申請画面でポチポチ入力して、いざ提出ボタンを押して、返事を待つこと数日。

大量の提出書類とともに、「Need more information」と題したメールが来ました。
中身をGoogle翻訳で確認していくと

  • 申請はすべて英語で行うこと
  • 提出した写真にもっとZoomを使ってるっぽいところを使え
  • 利用規約、サポートページ、特定商取引、プライバシーポリシーはすべて英語にしろ
  • 30項目くらいあるセキュリティアンケートに英語で答えなさい
    だいたいこんな感じでした、、、

大変すぎてやる気が出ません。。。
しかし、ここまで頑張って来て諦めるわけにはいきません。

必死こいてGoogle翻訳を使いながら、なんとか作り上げ、サポートとの英語でのやり取りを経て提出。

すると数日経って「Need more information」のメール

足りない点を補ったり、セキュリティに必要な実装を追加回収など行って、再度提出。

すると数日経って「Need more information」のメール

足りない点を補って再度提出。

すると数日経って「Need more information」のメール

こんな感じで5回ほどのやり取りを経たころには1か月以上がたっていました

5カ月ほどの歳月を費やして、ようやくconnecteeをリリース

長い道のりでしたが、やっとここまで来ました。

感動です。

やっぱり人に頼って作ってもらうしかできなかったころと比べ、一人で設計から何からすべて作れるようになったことで、何より気持ちが楽になりました。

webサービス公開後、すぐに新規開発案件に参画

webサービス公開後、中規模のマッチングwebアプリの新規開発案件への参画が出来ました。
いわゆる「ギャラ飲み」のwebアプリです。
4名(フロント2、サーバー1、インフラ兼フロントのバックアップリーダー)体制でのチーム開発でして、
僕はサーバーサイド兼管理画面を担当し、DBテーブル設計、APIエンドポイント設計、Laravelでのサーバーサイド開発、vue・Typescriptでの管理画面のwebフロント開発を担当しました。
テーブル数も40ほどあり、正直、一人でやるにはかなりきつかったですが、一人でやり切る力がついていたので、2カ月ほどで無事プロジェクトが完了しました。

それまでの経験が活き、要件定義を見てDB設計から一人で出来ましたし、connecteeのときよりもレベルアップしたと感じています。
ちなみにこのときにもwebsocketを導入したり、Dockerでの本番・検証環境構築も行い、覚えたてのTypeScriptを使ったりと、さらなる成長ができました。

チーム開発での実務は初めてでしたが、こちらはこちらで記事化できればと思います。

webサービス開発、それから実務経験を終えて感じたこと

1.初心者は「思考停止」でプログラミングスクールには行くな

僕は今まで御覧いただいた通り、プログラミングスクールには行っていません。

とはいえ、塾講師としてのキャリアがあるので、プログラミングスクール側の立場も一定の理解があると思っています。
ここからはその前提での、個人的な意見です。

ネットでいくらでも情報が出てくるこの時代、プログラミングスクールの価値っていうのは、

「教えてもらえること」ではなく、「モチベーション」だ
とか、
世の中には教えてもらわないと学べない人がいて、その人のためのサービスだ
とか、言われます。

そして、80万円などの高額な学費にも関わらず、"とりあえず"プログラミングスクールに行く人は、「将来の自分への投資」だと。

正直、思考停止だと思います。

「エンジニアになるための勉強」をするのではなく、「エンジニアになってからも成長し続けるための勉強方法を身につける」必要があると思います。
エンジニアになってからは基本的にすべて独学になるので、独学のほうがエンジニアになってから苦労しないのでは???と思ってしまいます。

ただし、第一言語の習得のための学習コストが最も大きいので、それを理解したうえで、一人で勉強する時間コストと天秤にかけての投資と考えて価値を見出せるような優秀な方なら、十分プログラミングスクールを有効活用できると思います。

ただ、思考停止でプログラミングスクール行くタイプの人の雰囲気を見ていると、エンジニアとして実務に入ってからも、先輩エンジニアに手取り足取り教えてもらってステップアップできると妄想を抱いている人がそれなりにいるように見えます。
会社の立場に立てば、そんな奴に給料払いたくないやろ、とわかるはずなんで、それがわかってない時点で厳しいのでは?と思ってしまいます、、、

2.プログラミング学習の継続に最も重要なモチベーションの動機付け

僕の場合、一回目のプログラミング学習で挫折した時と、二回目でうまく学習を継続できた時との最大の違いは、
実際にプログラミングで報酬を得たかどうか、に尽きます。
早すぎるタイミングでしたが、身につけたスキルでわずかながらも稼いだという成功体験を味わったことがモチベーションへの大きな寄与を果たしていると思います。

本当に自分が身につけることができて、お金になるかどうかが不安なまま膨大な学習を続ける不安は計り知れません。

その不安を早期に払拭できていたことが、その後の学習継続のモチベーション維持に間違いなく影響していたと思います。
大きな目標の前に小さな一歩一歩を積み重ねるほうがモチベーションは維持しやすいということです。

正直、このおかげで、僕は心が折れそうになったことはほとんどなかったです。
強いて言うなら、ZoomのAPI申請のときくらい(笑)

個人的には、プログラミングスクールにモチベーション管理を期待して通うよりはるかに有効な手段だと思うので、かなりおすすめの方法です!

3.自分で考えてwebサービスを作ることが成長への最短ルート

1年間の自分自身の成長曲線を考えると、connecteeの開発を始めたとき以降、それまでと比べて異常に伸びたと思います。

人が設計したものを作る受動的なときと、自分で設計からやる能動的なときとでは、吸収力が10倍と言ってもいいくらい違います。

また、自分で設計を経験し、インフラからフロントまで全ての工程を経験しておくと、自分の担当外のエンジニアがやりやすいかどうかまで配慮することができますし、絶対やっといたほうがいいな、と改めて思いました。

4.[最後に]プログラミングを楽しもう!!

僕はプログラミングが大好きです。
頭の中にあるイメージが実際に形を得て、思い通りに動くようになる瞬間がサイコーです。
初学者のうちはいっぱいいっぱいになりがちですが、モノづくりの喜びを楽しみながら勉強すると、継続しやすいと思います。

少しでもこの記事がプログラミング初学者の参考になれば幸いです。

Discussion