【和訳】Using Google Sheets as a Makeshift Database for React Apps【React×Googleスプレットシート】

本記事は[Using Google Sheets as a Makeshift Database for React Apps](https://itnext.io/using-google-sheets-as-a-database-for-react-apps-6c15b4481680)の和訳です。

ReactでGoogleスプレットシートからデータを取得する方法を調べていて、Metisというライブラリを見つけました。
MetisはReactでGoogleシートをデータベースとして使用するための高階コンポーネントです。
複数のシートからデータを取得して、グローバルな値として利用できます。感覚としてはContext APIに似ています。
React×GoogleシートでSPAを開発するならMetisが一番良いのかな、という所感です。

別途、チュートリアル記事の投稿予定です。

[Metis公式ドキュメント](https://athersharif.github.io/metis/index.html)
[Metis作者のTwitter](https://twitter.com/athersharif)



*-----以下和訳-----*

## Reactアプリの仮のデータベースとしてのGoogleスプレッドシートの使用

私たちはカスタムメイドのウェブサイトを作りたいと思っていて、小鳥さんがReactは最近のクールな子供たちが求めているものだと教えてくれました - Wordpressに比べて速くて、拡張性があり、更新が簡単なのですね？
でも、自分たちでコンテンツを更新できるようにしたい。なんでもかんでも、みたいな。あ、Post...え？Postgres？なんだそれ？いや、MySQLも知らない。Firebase？またまた技術専門用語に襲われた気がする! グーグルシートじゃダメなのか？

React と Wordpress を比較したことを謝罪します。 彼らは完全に別の獣であり、異なる目的を果たしていますーーーReactはJavascriptフレームワークであり、Wordpressはコンテンツ管理システム（CMS）です。Wordpressを椅子に縛り付けて、Hostel（3つの部分すべて）のようにしたり、ペイトリオッツのファンがトム・ブレイディを崇拝しているように、Wordpressを賞賛したりすることもできます（ごめんなさい、私はいつまでも永遠にイーグルスのファンなのです）。しかし、私は、私が知っている他のほとんどの人々のように、Wordpressから移行しました。理由は様々だが、Redditに最も適した理由だと思います。さて、Reactの話に戻りましょう。



### バックグラウンド

私は数年前、ボランティアのスタートアップEvoXLabsの一環として、FAWN Initiative (Free and Accessible Websites for Nonprofits)を運営していました。ほとんどの場合、これらのウェブサイトは情報を提供するもので、頻繁に更新が必要でした。しかし、このイニシアチブの背後にあるアイデアは、ウェブサイトのアクセシビリティを促進し、提唱することだったので、更新は取引の一部ではありませんでした。これはReactが選ばれた理由の一つでもあります。魔法のようにウェブサイトをアクセシブルにするのではなく、アクセシビリティを全く考慮して作られた、視覚的にも機能的にも魅力的なウィジェットの束ではなかったからです。AngularやVueもほとんど同じだったでしょうが、Reactは毒だったのです。とにかくアップデート。組織のスタッフやボランティアがReactを使いこなせるか、従来のデータベースを使ってナビゲートできるかの2つです。これはすぐに問題となり、需要に追いつくためのリソースが不足していたため、FAWN Initiative は活動を休止し、現在に至っています。


### Googleスプレッドシートへ

約1年前、私はReact開発者として、自分が大切にしている活動に貢献できる別の方法を考え始めました。非営利団体が自分でコンテンツを追加/削除/修正する際のボトルネックになることなく、非営利団体のためのウェブサイトを作ることはできないだろうか？そこで私は、一般的に人々が情報を保存したり取得したりするためにウェブ上で最も一般的に使われているツールは何かを尋ね始めました。テックの世界では、それに対する答えは、それ自体が本になるようなリストになっています。テックの世界以外では、Google Sheetsが唯一の答えとなっています。Excel/CSVファイルはそのリストの2番目にありましたが、変更を加えてファイルを展開するプロセス全体について、人々は躊躇していました。幸いなことに、Google Sheetsは他のほとんどのGoogle製品と同様に、非常に素晴らしいAPIを持っています。そして、APIあるところに光あり。

**Google Sheetsには伝統的なデータベースとの比較がなく、伝統的なデータベースの代わりになるものではないです。**しかし、その場しのぎのデータベースとしてのGoogle Sheetsが本当に有益であるかもしれない点の1つは、[伝統的なデータベースでは追加の手段で処理されていた](https://softwareengineering.stackexchange.com/questions/156220/ways-to-have-a-history-of-changes-of-database-entries)、[履歴の追跡性](https://support.google.com/docs/answer/190843?co=GENIE.Platform%3DDesktop&hl=en)です。

### 技術の話

さて、APIを用意しました。ReactはJavascriptのフレームワークです。[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)コールでいいんだよね？お好みであれば[axios](https://github.com/axios/axios)も 簡単でしょう？うーん、そうでもない。

Reactの優れた点の一つはルーティングです。ページをナビゲートするときにページ全体をリロードする必要がなく、サブコンポーネントだけをナビゲートすることができます。これが高速な理由です。では、いくつかのコンポーネント（この文脈ではページと同義）を持っていて、それぞれが`fetch`コールを持っているとしましょう。何が起こるでしょうか？コンポーネントがロードされるたびに（`fetchコールがどこに置かれているかにもよりますが）、ネットワークコールが発生します。そして、ネットワークコールは[パフォーマンスを大幅に低下させる](https://www.eurovps.com/blog/reasons-for-slow-website-loading/)可能性があります。しかし、それだけではありません。Google SheetsのAPIコールが行われるたびに、コール数のノルマに照らし合わせてカウントされます。

[Google Sheets API v4](https://developers.google.com/sheets/api)の[Usage Limits](https://developers.google.com/sheets/api/limits)の項より引用:
>このバージョンのGoogle Sheets APIでは、プロジェクトごとに100秒あたり500リクエスト、ユーザーごとに100秒あたり100リクエストという制限があります。読み取りと書き込みの制限は別々に追跡されます。1日の利用制限はありません。

長い話を短くすると、これらの制約を考えると、私たちが本当に望むのは、ネットワークコールを可能な限り制限することです。これにより、ホームページの高速化が図られ、ノルマを最大限に活用しています。予想されるトラフィックが使用制限を超えている場合は、従来のデータベースがあなたのニーズに最も適しているかもしれません。後述の「Googleシートを使わないとき」では、このようなシナリオを取り上げています。

### メティスとは

[Metis](https://github.com/athersharif/metis)は、ReactアプリがGoogle SheetsをMakeshiftデータベースとして使用できるようにする[高次コンポーネント(HOC)](https://reactjs.org/docs/higher-order-components.html)です。ご存知の方もいらっしゃるかもしれませんが、[Metis](https://github.com/athersharif/metis)はギリシャの知恵の女神にちなんで名付けられました。[Metis](https://github.com/athersharif/metis)には主に2つのコンポーネントがあります。`GoogleSheetsProvider`と`withGoogleSheets`です。

`GoogleSheetsProvider`はReactの[Context.Provider](https://reactjs.org/docs/context.html#contextprovider)に非常に似ています。これはReactアプリをラップし、Google Sheets Docからすべてのシートを取得し、APIからの生の結果を読み取り可能なkey/value(kv)のストアに変換し、このkvストアをコンテキストに公開します。これにより、コンポーネントツリーのどこからでもkvストアにアクセスできるようになります。

`withGoogleSheets`は、特定のシートのデータをコンテキストから取得し(`GoogleSheetsProvider`を介して)、[props](https://reactjs.org/docs/components-and-props.html)を介してコンポーネントで利用できるようにするための高次コンポーネントです。

デフォルトでは、`withGoogleSheets`は、Google Sheets APIからのデータ取得に失敗した場合(不正なパーミッション、クォータに達した場合など)にレンダリングするための非常に基本的なコンポーネントが同梱されています。このHOCでは、このデフォルトのコンポーネントをカスタマイズしたり、全く異なるカスタムコンポーネントに置き換えることができます。

`withGoogleSheets`は、単一のシート名またはシート名の配列を引数にとり、データを取得するように設計されています。それぞれを個別に指定せずにすべてのシートを取得することもサポートされており、[例](https://github.com/athersharif/metis/tree/master/example)を挙げて[よく説明されています](https://github.com/athersharif/metis/blob/master/README.md)。

#### 基本的な例

インストール
`npm install react-db-google-sheets --save`

.env

```.env
REACT_APP_GOOGLE_SHEETS_API_KEY=[YOUR-API-KEY]
REACT_APP_GOOGLE_SHEETS_DOC_ID=[YOUR-DOC-ID]
```

App.js

```React
import React from 'react';
import GoogleSheetsProvider from 'react-db-google-sheets';
const App = () => (
  <GoogleSheetsProvider>
    <MyApp />
  </GoogleSheetsProvider>
);
export default App;
```

Component (say Hello.js)

```React
import React from 'react';
import { withGoogleSheets } from 'react-db-google-sheets';
const Hello = props => (
  <div>
    {props.db.sheet1.map(data => (
      <span>{data.id}</span>
    ))}
  </div>
);
export default withGoogleSheets('sheet1')(Hello);
```

その他の例は[ドキュメント](https://github.com/athersharif/metis/blob/master/README.md)や[GitHubレポジトリ](https://github.com/athersharif/metis)の[examples subfolder](https://github.com/athersharif/metis/tree/master/example)に記載されています。

### Googleスプレッドシートの使用が不適な時

願わくばそろそろ、Google SheetsをReact Appsのためのその場しのぎのデータベースとして使うというアイデアに、少なくとも興味をそそられていることでしょう。しかし、これが良い解決策ではないというシナリオをいくつか考えているかもしれません。その通りです - そのようなケースはいくつかあります。**プログラミングの世界では文字通りすべてのことがそうであるように、ツールの使い方はニーズに依存していて**、Metisも例外ではありません。

第一に、先に述べたように、もしあなたのウェブサイトに大量のトラフィックが来ることが予想される場合は、`GoogleSheetsProvider`を使用して、最初のウェブサイトの負荷ごとに1つのネットワークコールを制限しても、伝統的なデータベースを使用するか、Google Sheets APIの使用のための有料プランを検討する必要があります。第二に、Google Sheetsをその場しのぎのデータベースとして使用するためには、ドキュメントのパーミッションを公開可能に設定する必要があります。そのため、もしあなたのデータにパスワードや機密情報が含まれていて、ユーザーのアクセス権限を保証する必要がある場合は、従来のデータベースを使用し、適切なセキュリティプロトコルを実装する必要があります。[Metis](https://github.com/athersharif/metis)やその場しのぎのデータベースとしてのGoogle Sheetsの使用は、情報提供サイトや履歴書・ポートフォリオサイトのように、一般に公開されているデータを対象としています。

最後に、外部キー（テーブル間の相互参照の役割を果たす列、Google Sheetsの用語ではシート）が必要な場合は、リレーショナルデータベースを使用した方が良いでしょう。[Metis](https://github.com/athersharif/metis)は、将来的にはGoogle Sheetsを使ったリレーショナルデータベースを実現するためのヘルパー機能やガイドラインを提供する予定ですが、**自分のニーズを評価し、ユースケースに最適なツールを決定することを強くお勧めします**。

**Updated:**
**何人かの人と話したのですが、Google Sheetsはそれ自体がデータベースではないことを再確認する価値があります。それはスケーラブルではないし、伝統的なデータベースの利点を利用していません。しかし、スケーラビリティが問題ではなく、CMSを構築することが非現実的であり、技術に精通していないコンテンツの管理者に新しいツールを教える必要がある場合には、オーバーヘッドが高すぎるというような非常に特殊なユースケースでは、Metisは有益なものになるかもしれません。ニーズとユースケースを評価し、目的に合ったツールを選択することは本質的に重要です。**

### 終わりに

[Metis](https://github.com/athersharif/metis)は、コードの変更や展開のプロセスなどを気にすることなく、Google Sheetsを使った簡単な操作でWebサイトのコンテンツの追加/変更/削除ができるツールを目指しています。また、Google Sheets Doc上のシートに色やフォントサイズなどを指定して、Webサイトのデザインやレイアウトを管理することもできます。可能性は無限大で、使いやすさはとてつもなくセクシーです。しかし、繰り返しになりますが、あなたはあなたのニーズを評価し、あなたの要件に最適なツールを選ぶ必要があります。


[Metis](https://github.com/athersharif/metis)を使ってみましょう。フィードバック、貢献、質問、すべて大歓迎です。[GitHubレポジトリ](https://github.com/athersharif/metis)に問題を書き込んだり、メールや[Tweet](https://twitter.com/athersharif)で質問やフィードバックを送ってください。


## 参考

[React開発効率を3倍にするVS Code拡張機能&環境設定](https://qiita.com/newt0/items/b7810fb38c339ec5e4a7)
[React初案件獲得までの流れ(学習・案件探し・面接・契約まで)](https://qiita.com/newt0/items/975a379de904858dd0f9)

[The Complete React Developer Course (w/ Hooks and Redux)](https://www.udemy.com/course/react-2nd-edition/)
[Universal React with Next.js - The Ultimate Guide](https://px.a8.net/svt/ejp?a8mat=3BK8OP+16V8C2+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Funiversal-react-with-nextjs-the-ultimate-guide%2F)
[React Native入門：ニュースアプリを作りながら覚えよう/Hooks対応 2020年版](https://px.a8.net/svt/ejp?a8mat=3BK8OP+16V8C2+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Freact-native-first-step%2F)
[React.js & Next.js超入門](https://amzn.to/2WwaXwQ)
[Webサイト高速化のための　静的サイトジェネレーター活用入門](https://amzn.to/3b5kDpd)
[詳解！ Google Apps Script完全入門 ～Google Apps & G Suiteの最新プログラミングガイド](https://amzn.to/3jSx8se)
<a href="https://www.amazon.co.jp/dp/B07X7DHZ9F/ref=as_li_ss_il?&linkCode=li2&tag=fden02-22&linkId=0b5b3306ff6ecee8f89a30f15b492aa9&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B07X7DHZ9F&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=fden02-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=fden02-22&language=ja_JP&l=li2&o=9&a=B07X7DHZ9F" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><a href="https://www.amazon.co.jp/dp/B0851BGDQG/ref=as_li_ss_il?&linkCode=li2&tag=fden02-22&linkId=fedb0f3b6f6cc9bbc2a5b25b79509ef5&language=ja_JP" target="_blank"><a href="https://www.amazon.co.jp/Web%E3%82%B5%E3%82%A4%E3%83%88%E9%AB%98%E9%80%9F%E5%8C%96%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE-%E9%9D%99%E7%9A%84%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E6%B4%BB%E7%94%A8%E5%85%A5%E9%96%80-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%82%A8%E3%83%93%E3%82%B9%E3%82%B3%E3%83%A0-ebook/dp/B088WJWJK9?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=UC7AQUH6OZCN&dchild=1&keywords=jamstack&qid=1613358356&s=digital-text&sprefix=JAMS%2Cdigital-text%2C278&sr=1-5&linkCode=li2&tag=fden02-22&linkId=4ef4eee5d8e31e0ccbb59b21c5bc47ca&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B088WJWJK9&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=fden02-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=fden02-22&language=ja_JP&l=li2&o=9&a=B088WJWJK9" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><a href="https://www.amazon.co.jp/Google-Apps-Script%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-%EF%BD%9EGoogle-Suite%E3%81%AE%E6%9C%80%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%AC%E3%82%A4%E3%83%89%EF%BD%9E-ebook/dp/B07BNB1Z9L?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=GAS&qid=1613358447&s=books&sr=1-1&linkCode=li2&tag=fden02-22&linkId=90c3880c2f5bcd22b0cc0497d5036f0a&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B07BNB1Z9L&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=fden02-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=fden02-22&language=ja_JP&l=li2&o=9&a=B07BNB1Z9L" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />