こちらはCrieitの個人開発サービスに用いられている技術 Advent Calendar 2018の2日目の記事です。
前日はなべさんの日本語のフリーフォントを一度に試せる「ためしがき」に用いられている技術についてでした!
11/5にNyaaanというWebサービスをリリースしました。
そこで
を書いていこうと思います!
どういうサービスかは以下の記事を読んでいただけたらと思います!
https://blog.haramishio.xyz/entry/service-nyaaan
ざっくりな構成でいうと
です。
Nuxt.jsはVue.jsアプリケーションを作るためのフレームワークです。
ちょっと大きめのVue.jsアプリを作る際に必要なVuexやVue Routerなどが入ってるのでNuxtをインストールすればすぐにWebアプリが作れます。
今回はSSR(サーバーサイドレンダリング)を行わないため、SPAモードで利用しています。
Webホスティングはさまざまな種類がありますが、今回はNetlifyを選択しました。
選択した理由としては・・・
npm run build
がビルドコマンドよ!ってNetlifyに登録しとくだけでいい)APIやDBが必要になったのですが、すべてFirebaseで行いました。
主要なFirebaseサービスはHostingとML Kit以外使いました。
それぞれの用途としては・・・
FirestoreはNoSQLです。RDBのような柔軟なクエリーを書くことは出来ません。
その制限にひっかかってちょっと苦しんだ事例があるので共有します。
Nyaaanでは「有効期限」という機能があり
これを設定すると1時間または1日経つと、鳴き声(つぶやきみたいなもの)が見れなくなるというものです。
その鳴き声テーブルはこんな感じになってます(本当はもっとカラムあります)
カラム | 型 |
---|---|
ID | string |
鳴き声 | string |
本音 | string |
有効期限 | timestamp |
作成時間 | timestamp |
Nyaaanにはタイムラインがあり、鳴き声は作成時間の降順でソートしたいです。
なので・・・
// カラム名はわかりやすく日本語にしてます
mewRef.where("有効期限", ">", now).orderBy("作成時間", "desc").limit(10).get()
としたかったのですがこれはNG。
範囲フィルタ(>や>=)を使う場合は、orderByの最初の要素はその範囲フィルタで使用したカラムしか指定できません。
Cloud Firestore でのデータの並べ替えと制限
RDBならこういうのは普通にできますが、NoSQLはこういう制限があるのかと勉強になりました。
結局どうしたかというと、後述するバッチ的なもので有効期限をチェックして削除してます。
上述したバッチ的なものの話です。
サービスを作っていくとバッチが必要になる場面があるとおもいます。
なにかしらの処理を定期的に動かすとなるとCronを使ったりJenkinsを使ったり色々あると思います。
これらはサーバーが必要になりますよね。
すでに持ってる人はそれを使えば良いんですが、僕はお金をかけたくないのでどうにかしてサーバーレスにしたいです。
さて、FirebaseのFunctionsはHTTPSフックで起動することが出来ます。
つまりcronでcurlを定期実行すればバッチみたいなことができるわけです!
そして世の中には外形監視のために定期的に指定したURLを叩いてくれるサービスがあります。
cron-job.orgやUptime Robotがそれです。
これを利用してFunctionsを定期的にトリガーするようにしてバッチ処理をサーバーレスで実現しました。
懸念点として、Functionsの実行を外部からできるようにしてしまっているのでセキュリティ的に問題ないのか?という点ですが
今回の場合はリクエスト時にGETパラメーターでアクセストークンを渡しており、そのアクセストークンじゃないとアクセス拒否するようにコーディングしています。
それでも攻撃されて突破されるリスクもなくはないので、センシティブなことをしたい場合はやめたほうがいいと思います。
Fucntionsのトリガーは色々あります。
トリガー | 内容 |
---|---|
HTTPS | URLを叩くだけ |
onCall | クライアントから直接呼び出し |
Authentication | ユーザの登録/削除で呼び出し |
Firestore | ドキュメントの登録/更新/削除で呼び出し |
Storage | オブジェクトの登録/更新/削除で呼び出し |
Pub/Sub | Cloud Pub/SubのPublishで呼び出し |
NyaaanではHTTPSとAuthenticationのトリガーを使用してます。
特にAuthenticationトリガーは便利で、以下のようにFunctionsに書くだけで簡単に書くことが出来ます。
// ユーザが削除されたら実行されるFunction
exports.removeUser = functions.region('asia-northeast1').auth.user().onDelete(function(user, context) {
~~~
});
Nyaaanではユーザ削除されると今までの鳴き声が消えるようになってます。
クライアントでそこまでやると重いので、クライアントではAuthenticationのユーザだけ削除してレスポンスをすぐ返し、
FunctionsのAuthenticationトリガーで非同期で削除処理を走らせてます。
Nuxt.jsのSPAモードを使用していて、Netlifyでホスティングしていたのですが
ルートパス以外を直接呼び出すと404エラーになってしまいます。(例: https://nyaaan.haramishio.xyz/top)
SPAではルートパス以外でアクセスされたらindex.htmlへリダイレクト処理をする必要があります。
Netlifyはリダイレクトの機能があり、デプロイするディレクトリのトップに _redirects
を配置しそこにリダイレクト設定を記述するとリダイレクトしてくれます。
/* /index.html 200
この話をもうちょいちゃんと説明したのがこちらの記事になります。
Netlifyを使ってたらルートパス以外が404になった話とその解決方法
ということでNyaaanの使用技術とそこから得た知見を書きました!
この記事でみなさんの開発のヒントになれれば幸いです!
副業募集中😀 #AWS #GCP #golang #Python #Vim #技術ブログ #SRE #しがないラジオ #インフラ勉強会 欲しいもの: https://t.co/wZbbiO4e3d
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント