tag:crieit.net,2005:https://crieit.net/tags/Apollo/feed 「Apollo」の記事 - Crieit Crieitでタグ「Apollo」に投稿された最近の記事 2019-09-26T22:08:54+09:00 https://crieit.net/tags/Apollo/feed tag:crieit.net,2005:PublicArticle/15427 2019-09-26T22:08:54+09:00 2019-09-26T22:08:54+09:00 https://crieit.net/posts/React-PWA-Rails-GraphQL-RPG React PWA + Rails GraphQLで作ったポモドーロRPGに使った技術やその選定理由を書いてみた <p>先日、『<a target="_blank" rel="nofollow noopener" href="https://www.g-g-g-g.games">g4</a>』というポモドーロ+RPGなサービスをリリースしました。</p> <p>そのサービスで使った技術について聞かれることがあったので残しておきます。</p> <h1 id="どんなサービス?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%3F">どんなサービス?</a></h1> <p>ポモドーロ・タイマーを使い25分間集中すると経験値をもらえ、その経験値でレベルが上がる。<br /> って言う感じのやつです。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.g-g-g-g.games">https://www.g-g-g-g.games</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://www.g-g-g-g.games"><a href="https://crieit.now.sh/upload_images/4857e38ac110f7f2ccb9a3a6c9851f425d8c46a290533.jpeg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4857e38ac110f7f2ccb9a3a6c9851f425d8c46a290533.jpeg?mw=700" alt="https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_51402_6c1fef60-9f24-2233-821b-1b4b16575e21.jpeg" /></a></a></p> <h2 id="こんな特徴があります。"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E7%89%B9%E5%BE%B4%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82">こんな特徴があります。</a></h2> <ul> <li>ポモドーロ・タイマーやRPG的なUIはリッチで動きがある</li> <li>現在のステータスをOGP画像にしてシェアできる</li> <li>上昇する能力値や覚えるスキルは登録した文章を解析して決まる</li> </ul> <h1 id="構成はこんな感じ"><a href="#%E6%A7%8B%E6%88%90%E3%81%AF%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98">構成はこんな感じ</a></h1> <p><a href="https://crieit.now.sh/upload_images/a91960cfcbabfe4677662c7e3a35b9225d8c468610acb.jpeg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a91960cfcbabfe4677662c7e3a35b9225d8c468610acb.jpeg?mw=700" alt="https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_51402_1f7797cd-59e5-b556-2afe-b0a964acd0ac.jpeg" /></a></p> <h2 id="フロントエンドの選定理由"><a href="#%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E3%81%AE%E9%81%B8%E5%AE%9A%E7%90%86%E7%94%B1">フロントエンドの選定理由</a></h2> <p>フロントエンドはSSRしたReactアプリをfly.ioにおいています</p> <h3 id="[React]"><a href="#%5BReact%5D">[React]</a></h3> <p>自分は過去に仕事でNuxt.jsや生Vue.jsを使ったことがあり、個人ではExpoやNext.jsでReactにも触っていました。</p> <p>今回Reactを選択した理由は以下です。</p> <ul> <li>型が欲しかった。Typescriptを使いたかった</li> <li>Reactのほうが書いていて楽しい(個人の感想です) <ul> <li>React Hooksめっちゃいい</li> </ul></li> <li>Apolloを使うならVueよりReactのほうが色々揃っている</li> </ul> <h3>[<a target="_blank" rel="nofollow noopener" href="https://fly.io">fly.io</a>]</h3> <p>SSRするためにNode.jsをホスティングするやつが欲しかったので選定。<br /> <a target="_blank" rel="nofollow noopener" href="https://mizchi.hatenablog.com/entry/2019/02/21/235403">mizchiさんのブログ</a>で知り、面白そうだなと思ったのがきっかけ。<br /> べつにfirebase hostingでもよかったですが、以下が決め手</p> <ul> <li>firebase hosting同様初期導入費用がほぼ0</li> <li>CDN</li> <li>キャッシュコントロール</li> <li>svgを使ったOGP画像の生成ができる</li> </ul> <p>特に、</p> <blockquote> <p>svgを使ったOGP画像の生成ができる</p> </blockquote> <p>に有用性を感じて選定したんですが、現時点ではカスタムフォントと日本語への対応が十分でなく、別途Cloud Runを使うことになってしまっています(後述)<br /> (サポートに聞いたらリポジトリ教えてもらったので(OSS)対応できるようなら自分で対応してなげたいなぁ)</p> <h5 id="キャッシュコントロールもよい"><a href="#%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%82%E3%82%88%E3%81%84">キャッシュコントロールもよい</a></h5> <p>キャッシュの操作も面白くて、<br /> g4の公開用ページではAPIからもらった結果をキャッシュして、キャッシュがあればそれをそのまま返すということをしています。</p> <p>これによってAPIサーバーへの負荷はかなり低くなってると思います。<br /> APIサーバー側からは、データ更新時にfly.ioのキャッシュを削除する操作をしていて、データが更新されるまではfly.ioはキャッシュを使い続けてます。</p> <p>この辺のAPIが普通に使いやすくて簡単にかけるのでめっちゃ良きです。</p> <h5 id="fly.io良いよ"><a href="#fly.io%E8%89%AF%E3%81%84%E3%82%88">fly.io良いよ</a></h5> <p>fly.io自体ははデプロイも早いし、導入コストも安いので<a target="_blank" rel="nofollow noopener" href="https://zeit.co">now</a>とかと並べて、手軽にNode.jsをホスティングするための選択肢にしてもいいんじゃないかなって思います。</p> <h3 id="Next.jsを選ばなかった理由"><a href="#Next.js%E3%82%92%E9%81%B8%E3%81%B0%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E7%90%86%E7%94%B1">Next.jsを選ばなかった理由</a></h3> <p>SSRする予定ではありましたが、OGPだけ生成できればいいなというレベルだったので、通常のReactアプリで作りました。<br /> なるべく継続開発するため、アップデートの手間と依存を減らしたかったのも少しある</p> <h3 id="[PWA]を選定した理由"><a href="#%5BPWA%5D%E3%82%92%E9%81%B8%E5%AE%9A%E3%81%97%E3%81%9F%E7%90%86%E7%94%B1">[PWA]を選定した理由</a></h3> <p>最初は、<a target="_blank" rel="nofollow noopener" href="https://expo.io">Expo</a>で作ろうかと思っていました。</p> <p>もともとSPAでアプリっぽいUIを作る仕事を受けたときに、Nuxt.js + Firebaseで作り、マルチブラウザ対応が辛いと思った経験がありました。</p> <p>RNならその辺いい感じに作れるかもと思って<a target="_blank" rel="nofollow noopener" href="https://shwld.net/seicho-release/">みんなの成長</a> というアプリでExpoを試しみて、使い勝手が良い事までは確認してました。</p> <p>ただ今回はモバイルより、デスクトップアプリのほうが欲しいということに気づき、<br /> Electronで作りやすかったり、PWAならそのままインストールもできちゃうのでWebでいいかなって思いPWAにしました。</p> <p>なのでマルチブラウザ辛いは解決してないです。<br /> ここは個人開発なので修行と割り切って本業に生かしていきます。<br /> Safari対応が結構めんどいけど、ユーザー多くて無視できない...</p> <p>マルチブラウザと言っても、現状Chrome、Safari以外はほぼ無視してまっす。</p> <h3>[<a target="_blank" rel="nofollow noopener" href="https://www.apollographql.com">Apollo Client (react-apollo)</a>]</h3> <p>これもSPAでアプリっぽいUIを作る仕事で、Nuxt.js + Firebaseで作ったときに、Firebaseのデータベース(このときはrealtime database使ってた)をフロントに反映するのが辛くて、同じようにREST APIも辛いだろうなと思って、GraphQLに手をだしたのがきっかけでした。</p> <p>GraphQLだけでもすごく良いのですが、Apollo Clientがいいのはキャッシュコントールで、<br /> クエリ毎にキャッシュを優先するかサーバーを優先するかを選択できます。</p> <p>また、キャッシュがあれば再取得しないなどを簡単に書けたり、とにかくこれはSPAのベストプラクティスだなって感じの実装をシンプルに書けます。</p> <p>Mutationするとキャッシュが書き換わったりするのもめっちゃ良き</p> <p>正直この辺のこと考えながらSPA実装するのってかなり大変じゃない?ってか大変だった<br /> アプリライクなUIのSPAならApollo Client使おうぜ!</p> <p>こいつのおかげでこれまたAPIサーバーの負荷はまあまあ抑えられてそうです。</p> <h2 id="[Firebase Auth, Storage]について"><a href="#%5BFirebase+Auth%2C+Storage%5D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">[Firebase Auth, Storage]について</a></h2> <p>バックエンドはRailsですが、APIサーバー作るのに正直Deviseとか使いたくないです(完)</p> <p>Twitter連携やら諸々簡単なので選ばない理由がない。<br /> Auth0は選択肢に入るけど今回GCPなのでGoogleでまとめられるし、そこまで込み入った認証必要ないしでこれにしました。</p> <p>Storageは別に何でもよかったですが、Firebase Authの認証ユーザー単位での権限指定が楽なので使い勝手は良いです。</p> <h2 id="デザインについて"><a href="#%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">デザインについて</a></h2> <p>g4のデザインはレスポンシブのヘルパーとして<a target="_blank" rel="nofollow noopener" href="https://github.com/twbs/bootstrap/blob/master/dist/css/bootstrap-grid.css">bootstrap-grid</a>だけ使わせてもらってます。<br /> めっちゃ便利なのでおすすめ。</p> <p>それ以外はcss全部自分で書いてます。</p> <p>コンポーネントファーストで作成しており、Atomic Designの粒度で、<a target="_blank" rel="nofollow noopener" href="https://storybook.js.org">Storybook</a>作ってコンポーネントを作ってる感じです。<br /> Storybookは割とぶっ壊れやすかったり、他のビルド設定と競合とか重複したり、辛みもありますが、<a target="_blank" rel="nofollow noopener" href="https://storybook.js.org/docs/testing/structural-testing/">storyshots</a>によるスナップショットの差分確認ができるのと、テストの安心感があるので、無いと無いで不安ではあります。</p> <h2 id="バックエンドの選定理由"><a href="#%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E3%81%AE%E9%81%B8%E5%AE%9A%E7%90%86%E7%94%B1">バックエンドの選定理由</a></h2> <h3>[<a target="_blank" rel="nofollow noopener" href="https://graphql-ruby.org">graphql-ruby</a> & Ruby on Rails]</h3> <p>Apollo Clientの項で書きましたが、GraphQLを使うことは決まっていました。<br /> GraphQLをマネージドでホスティングしてくれるやつを探したりしたんですが、普段Railsエンジニアなので慣れてるからテストとかも書きやすいしRailsでいっかで、graphql-rubyにしました。</p> <p>Railsにするとランニングコストは割とかかるんですが、今回は個人開発のメインに据えて長く継続開発したいを目的にしてたので、<br /> 稼働してないものにお金払うみたいなことにならない想定(自分が使い続ける)で、コストかける覚悟はしました。</p> <p>graphql-rubyは仕事でも使ってるので、今後も押していきたい存在。</p> <h3 id="[GCP/App Engine]"><a href="#%5BGCP%2FApp+Engine%5D">[GCP/App Engine]</a></h3> <p>App Engineについては<a target="_blank" rel="nofollow noopener" href="https://qiita.com/shwld/items/e86ee3f642c7857dd56e">こちらの記事</a>で書きました。</p> <p>要約するとHerokuでも良かったけど、使ってみたかったのでGCPにした。です。</p> <h2 id="[GCP/Natural Language API]"><a href="#%5BGCP%2FNatural+Language+API%5D">[GCP/Natural Language API]</a></h2> <p>便利。Azureとかにもありますが、今回はGoogle統一で行きました。くらいの選定理由</p> <h2 id="[GCP/Cloud Run]について"><a href="#%5BGCP%2FCloud+Run%5D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">[GCP/Cloud Run]について</a></h2> <p>Cloud Runは今回使う予定は全くありませんでした。</p> <p>今利用している理由としては、</p> <ul> <li>fly.ioでOGPを生成できるとふんでいたができなかった。</li> <li>とりあえず手っ取り早くカスタムしたDockerimageでfry.ioをあまりお金をかけずに使えるとこはないか。</li> </ul> <p>からの、Cloud Run。</p> <p>中身は日本語とフォントをインストールした普通のNodeイメージに<br /> fly.ioのサーバーを単純に乗っけて起動しているだけです。(プレビルドして実行したいがやり方が分からずdevサーバー起動しているのでなんとかしたい。誰かやり方知りませんか。)</p> <p>なので、いずれはfly.ioだけでできるようして、Cloud Runをやめたいです。</p> <h4 id="Cloud Run超便利"><a href="#Cloud+Run%E8%B6%85%E4%BE%BF%E5%88%A9">Cloud Run超便利</a></h4> <p>そんな理由で使い始めましたが、驚くくらい簡単かつ手軽にカスタムDockerイメージが使えるので、Cloud Runめっちゃ便利です。<br /> 今後活用していきたい。</p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>割と構成的にはガチよりになりました。<br /> 自分の技術力総動員してる感じなのでテンション上がってめっちゃ楽しい!</p> <p>g4の運用を支える技術についても今後書いていきたいです。</p> <p>みんなでレベル上げしましょう!</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.g-g-g-g.games">https://www.g-g-g-g.games</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://www.g-g-g-g.games"><a href="https://crieit.now.sh/upload_images/4857e38ac110f7f2ccb9a3a6c9851f425d8c46a290533.jpeg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4857e38ac110f7f2ccb9a3a6c9851f425d8c46a290533.jpeg?mw=700" alt="https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_51402_6c1fef60-9f24-2233-821b-1b4b16575e21.jpeg" /></a></a></p> shwld