Nuxt,Netlify,Contentful,Python,Firebase,Herokuを使った無料でサーバレスな複業メディアサイトを作った話

# 何を作ったか
エンジニア向けの複業(副業)メディアサイトを作りました。
複業(副業)関連のニュースを毎日自動で更新して配信してます。
https://fukugyou.dev/

自分自身2年ほどエンジニアとして複業をしていて、今後もっと複業(副業)をする、興味を持つエンジニアは増えると思いますし、個人的にはもっと複業の良さを知ってほしいという思いがあります。
もちろん複業にはメリットデメリット、色々な意見があると思っていますが、そこも含めて世の中の複業にまつわるニュースを集約してフラットに情報提供出来る場があると良いなと思い当サイトを作りました。

個人で開発を進めておりましたがフロントエンドとバックエンド含めて、ある程度形になったので全体の構成についてまとめようと思います。

# どう作ったか
## 概要
<img width="625" alt="スクリーンショット 2019-08-26 19.22.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110485/9620c665-b17f-b0ae-ae8d-a52de700efc6.png">

## アーキテクチャ、プラットフォームの選定基準
まず個人開発なのでインフラの構築等、本来のアプリケーション開発以外で時間を使うのが嫌だったのでなるべくサーバレス(インフラの事は考えない)構成にしたいという思いはありました。
また出来るだけ無料で使えるものに収めたいというのも個人的には重要な選定基準でした。

この手の個人開発サービスはリリースしても多くの場合がそんなに使われる事なく自然と消えていくものだと思っています。
(以前個人でiOSアプリを作ってリリースした時もそうでした。。)
そこで大事なのは個人で改善や開発を継続し続けるモチベーション管理だと思いますが、個人的には「ユーザー数が少なくマネタイズも出来ないのにサービスの維持コストだけかかる」という状態がモチベーション低下になると思っていたので、初期段階は出来るだけ無料で運用できるようにしたいと思ってました。

ここは単に個人開発のモチベーションコントロールの問題なので、逆にAWSなどを使ってお金を払いながらも個人サービスを開発した方がお尻に火がついて良いみたいな場合もあるかもしれません。

今回選定しているサービスやプラットフォームは全て無料で使える範囲で利用しているので
同じように無料でできる範囲内で個人サービスを開発してリリースしたいという方のご参考になればと思います。

(※無料といいつつドメイン代だけはお金を払っています。ドメインも気にしない方であれば完全無料にする事もできます)

## フロントエンド
### [Nuxt](https://ja.nuxtjs.org/)
[Nuxt](https://ja.nuxtjs.org/)自体の説明は省略しますが、Nuxtを選択した理由を簡単にまとめます。
ここはほぼ個人的な理由なのであまり一般化できないですが、本業や自分が今やっている複業などの環境含めて、Nuxtを使う(見る)機会が多かったのでNuxtにしましたというのが1番大きい理由です。

あとは今回は高速化のため静的ファイルをベースにサイトを作りたかったので静的ファイルを簡単にジェネレートできるNuxt([nuxt generate](https://ja.nuxtjs.org/guide#%E9%9D%99%E7%9A%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%94%9F%E6%88%90))を選択したというのも大きいです。後述するNetlifyとも相性が良いです。

ただこの理由もおそらく全てNuxtじゃないと出来ない、というわけではないのでReactなどを使っても同様の事は可能だと思いますので最終的には個人のスキルセットや環境に合わせて選択するのが良いかなと思ってます。

また今回はNuxtと合わせてUIフレームワークで[Vuetify](https://vuetifyjs.com/ja/)を使っています。
デザインスキルが低く、ゼロベースでUIを作るのが厳しいと思っていたので何かしらのUIフレームワーク(cssフレームワーク)を使おうと思っていました。
[Bulma](https://bulma.io/)や[Bootstrap](https://getbootstrap.com/)等検討しましたがVue.jsのアプリケーションと相性が良さそうなVuetifyを選定しています。


### [Netlify](https://www.netlify.com/)
[Netlify](https://www.netlify.com/)は静的ファイルのホスティングサービスです。
webサイトを公開するのに自分でインスタンスを立ててサーバを用意するというのがめんどくさかったので静的ファイルとセットでホスティングできるサービスを使ってフロントエンドのサーバを用意できるプラットフォームを選定しました。(サーバレス構成)
ホスティングサービスに関しては、[GitHub Pages](https://pages.github.com/)や[Firebaseホスティング](https://firebase.google.com/docs/hosting/?hl=ja)、AWSのs3+CloudFrontなどありますが、それらと比べてNetlifyが良かったのはこの辺です。

* Nuxtと相性が良い(Nuxt ジェネレートで簡単に静的ファイルをホスティングできる。Nuxtの公式ドキュメントもNetlifyを使っている)
* GitHubと連携してデプロイが簡単にできる
* GitHubのプルリクエスト単位でテスト環境を用意できる
* Netlifyフォームなどホスティング以外の機能も利用できる(お問い合わせ機能で使ってます)

またNetlifyは[無料プラン](https://www.netlify.com/pricing/)も用意されているので個人で簡単なサイトを公開する程度であれば無料の範囲内で十分問題ないのも大きい理由です。

### [Contentful](https://www.contentful.com/)
[Contentful](https://www.contentful.com/)とはヘッドレストCMSです。(UIを持たずにAPIベースでブログの投稿、参照などの機能を提供するプラットフォーム)

今回のサイトは自分でもブログ的にエンジニア向けの複業関連記事を提供したかったので、ブログの投稿、参照機能が必要でした。
ブログといえばWordPressが1番有名ではありますが使うモチベーションがほぼなかったので、こちらもNuxt、Netlifyとも相性がよくてサーバレスで運用出来るContentfulを使ってます。
またNuxt,Netlify,Contentfulを使ったCMS構築の記事があったので技術選定と実装面も含めて参考にさせて頂きました。

* [Nuxt.jsとContentfulでブログ作ってみた](https://qiita.com/hisako135/items/082115b50df92ef3e941)
* [【入門】Nuxt.js + Contentful + Netlify で始める、JAMstack な CMS 構築](https://qiita.com/isihigameKoudai/items/3e45ade7c438176a4cc9)

## バックエンド
### Python
APIからデータの取得、スクレイピング、Firebase操作、Herokuのデプロイなどを行うだけなので正直言語としてはなんでも良かったです。
個人的に最近はPythonが書きたい気分だったのでPythonにしました、以外の理由はほぼないです。。
一応FirebaseやHerokuでPythonも言語としてサポートされているので使っても大丈夫そうだなという裏どりくらいはした程度です。

### [Firebase](https://firebase.google.com/?hl=ja)
[Firebase](https://firebase.google.com/?hl=ja)はもともとはmBaaS(mobile backend as a Service)と言われるモバイルのバックエンド構築をサポートするプラットフォームですが、最近はモバイル以外のwebアプリケーションでも使える機能が増えてきています。

今回使ったのはその中で[Firestore](https://firebase.google.com/docs/firestore/?hl=ja)だけです。
データストアとして使えるプラットフォームを探していましたがなかなか無料で使えるものが多くない(自分で探した範囲内では。。)のとRDSまで行かなくても単純なKVSレベルでも十分だったのでFirebaseを使うことにしました。
またFirestoreも無料で使える範囲があるのでそこにうまく収めれば良さそうだったのと、個人的にFirebaseをもうちょっと使ってみたかった(過去Firebaseのリアルタイムデータベースをちょっとだけ触った事があるくらい)というのも理由としてありました。

また今回のFirestoreは無料枠だと50,000リクエスト/日しかなかったので、なるべくFirestoreへのリクエストを減らすための工夫をしてます。
具体的にはクライアント側から直接Firestoreを見ずに、Nuxtのジェネレートのタイミングで一度だけFirestoreのデータを参照し、結果をjsonファイルに保存し、クライアント側ではjsonファイルを参照するようにしてます。
そうする事で毎回Firestoreへリクエストを飛ばす必要がなくなるので、無料枠も使いきる事がなくなるはずです。
詳しくはこちらをご参照ください。

* [Nuxtでビルド時にAPIを静的化して、完全にサーバーへのリクエストをなくすト](https://qiita.com/soichiro_nitta/items/7ca238d76072eba2ed97)

### [Heroku](https://jp.heroku.com/)
[Heroku](https://jp.heroku.com/)とはPaaS(Platform as a Service)と呼ばれるプラットホームでwebアプリケーションを構築するうえで様々な機能を提供してくれるサービスです。

今回使ったのは一部分だけで、cron処理による定期実行を実現したかったので
[Heroku Scheduler](https://devcenter.heroku.com/articles/scheduler)を使っています。
最近だとFirebaseでもcronのような定期実行ができるようなので、そちらでも良さそうです。

ただFirebaseのcronだと無料では使えない？(ここ正確にためしてないので違ってたらすまません。。)
ですがHerokuであれぼwebアプリケーションと合わせて一定の[dyno](https://jp.heroku.com/dynos)であれば無料で使えます。
1回1分以内で、1日2,3回動くバッチ処理であればHerokuの無料枠を使ってHeroku Schedulerが使えるのでとても便利です。
1000dyno/月までが無料の範囲内ですが実績としては1日1分以内のバッチ処理が2,3回動いて3dyno/月くらいしか使ってないのでかなり余裕だと思ってます。

Heroku schedulerについては数年前に個人的に使った事があり、その実績もあったので今回も採用しました。
(数年前と同じ技術選定をするのが変化の早いこの業界で良いのか悪いのかが微妙な気分にはなりますが。。。)

* [Qiita API(PHP)とHerokuを使って自動更新の記事を作る](https://qiita.com/hikarut/items/f6349e74fd02eb94a2ab)

# 最後に
正直作ったものもや使っているプラットフォーム等も目新しいものはありせん。
ただ色々と組み合わせて使う事でフロントエンド、バックエンドが組み合わさったそれなりのアーキテクチャのウェブアプリケーションが作れると思います。
今回使ったサービスやプラットホームはどれも非常に使いやすいですし、難しいものもあまりないので
これくらいであれば比較的短期間で簡単なサービス公開までできると思うので個人開発の参考になればと思います。