どうも。つじけ(tsujikenzo)です。今日は単発で 「スプレッドシートをJSONでWebAPI化しよう」 をお届けします。
この記事は、#Effective GoogleAppsScriptタグがついております。
はじめに
GASで業務アプリケーションを開発するときに、「規模が大きいなぁ」と悩んだことはありませんでしょうか。
下図のように、業務が多岐にわたるばあい、どのようにシステム設計すればいいのか、悩みはつきません。
そこで、業務ごとにアプリケーションを切り離し、データだけをやりとりする手法を検討してみます。
JSONとWebAPI
図の「受注履歴」の管理業務は、たしかに、今回の業務アプリケーションに必要な機能です。
しかし、双方向で頻繁にデータをやり取りすることはない(主に、一方通行)ので、機能を切り離し、メインの業務アプリケーションの負担を軽減させよう、というのが今回の趣旨です。
切り離したアプリケーションとのデータの受け渡しは、JSONで行います。
この、2つ(またはそれ以上)のアプリケーションが、JSONでデータを受け渡しあう仕組みを、WebAPIと呼びます。
2022年現在、WebAPIで受け渡しあうデータのフォーマットは、JSONがほとんどです。
JSONは軽く、JavaScriptをもとにしたデータ形式なので、とても扱いやすいデータ形式です。
JSONについては、こちらのブログも参考にしてください。
それでは、みなさんのGAS開発にも、WebAPIを取り入れてみましょう。
今日のアジェンダ
- WebAPIとはなにか
- JSONを作成する
- 呼び出される関数を書く
- Webアプリとして公開しよう
- デプロイ(Webアプリとして公開)しよう
- 外部アプリからJSONを取得しよう
WebAPIとはなにか
WebAPIとは、アプリケーションとアプリケーションがデータを受け渡し合う窓口のようなものです。
GASは、プロジェクト全体を、WebAPIとしてデプロイ(Webアプリとして公開)ができます。
つまり、スプレッドシートやGmailのデータを、他のアプリケーションにJSONで渡すことができるのです。
WebAPIは、外部から呼ばれることで、JSONを渡します。
これから、以下の手順で、作業を行います。
- JSONを作成する
- 呼び出される関数を書く
- デプロイする
JSONを作成する
このようなスプレッドシートを用意しました。ダミーデータなので、値はなんでも構いません。
見出しをつけた構造化データにしましょう。
すべてのスプレッドシートの値を、見出し(key)と値(value)が連想配列になった、オブジェクト形式に変換します。
const sheet = SpreadsheetApp.getActiveSheet();
const [headers, ...records] = sheet.getDataRange().getValues();
const recordsWithKey = records.map(record => {
const obj = {};
headers.map((key, index) => obj[key] = record[index]);
return obj;
});
return recordsWithKey;
オブジェクトを、JSONに変換します。
const json = JSON.stringify(recordsWithKey);
JSONをブラウザで操作するための、TextOutput形式に変換します。
const textOutput = ContentService.createTextOutput(json).setMimeType(ContentService.MimeType.JSON);
これで、JSONの準備ができました。
これまでのコードをクラス化します。
class OrdersSheet {
/** OrdersSheetに関するコンストラクタ
* @constructor
*/
constructor() {
this.sheet = SpreadsheetApp.getActiveSheet();
}
/** recordsを連想配列で返すメソッド
* @param{object}
*/
getHashRecords() {
const [headers, ...records] = this.sheet.getDataRange().getValues();
const recordsWithKey = records.map(record => {
const obj = {};
headers.map((key, index) => obj[key] = record[index]);
return obj;
});
return recordsWithKey;
}
/** recordsをJSONで返すメソッド
* @param{object}
*/
getJson() {
const hashRecords = this.getHashRecords();
const json = JSON.stringify(hashRecords);
const textOutput = ContentService.createTextOutput(json).setMimeType(ContentService.MimeType.JSON);
return textOutput;
}
}
/**
* TEST用関数
*/
function testOrderSheet() {
const o = new OrdersSheet();
console.log(o.getJson().getContent());
//[{"受注ID":"j001","受注日":"2022-01-31T15:00:00.000Z"
}
呼び出される関数を書く
GASのプロジェクトを、Webアプリとして公開したとき、呼び出されるのがdoGet()関数です。
「doGet」という関数名が決まっているので、自由に変えられません。気をつけてください。
関数の中身は、1行です。
function doGet() {
return new OrdersSheet().getJson();
}
デプロイ(Webアプリとして公開)しよう
スクリプトエディタの右上の「デプロイ」をクリックして、「新しいデプロイ」をクリックします。
新しいデプロイウィンドウの歯車アイコンをクリックして、「ウェブアプリ」だけにチェックが入っていることを確認します。
以下のように設定します。
- 新しい説明文・・・日本語でもかまいません
- 次のユーザーとして実行・・・「ウェブアプリケーションにアクセスしているユーザー」
- アクセスできるユーザー・・・「自分のみ」 ※アクセスできるユーザーは、ドメイン内に設定も可能です。セキュリティを気をつけて設定しましょう。
ウェブアプリのURLが発行されるので、コピーしてどこかにメモしておきましょう。
外部アプリからJSONを取得しよう
出力用に、別のスプレッドシートを用意しました。今回は、すべてのデータをそのまま貼り付けます。(必要に応じて「処理済み」データのみを貼り付ける、などデータを加工しましょう)
WebAPIを呼び出すコードはこちらです。
const url = 'ウェブアプリのURL';
const response = UrlFetchApp.fetch(url);
受け取ったレスポンスをJSON形式に変換します。
const json = JSON.parse(response.getContentText());
JSONを2次元配列に戻して、スプレッドシートに貼り付けました。
const values = json.map(element => Object.values(element));
SpreadsheetApp.getActiveSheet().getRange(2, 1, values.length, values[0].length).setValues(values);
このような結果になります。
まとめ
以上で、「スプレッドシートをJSONでWebAPI化しよう」をお届けしました。
業務アプリケーションを分割し、WebAPIでやり取りする手法は、マイクロサービスとも呼ばれています。
マイクロサービスには、ほかにもさまざまな役割や意味がありますので、今後もアップデートしていきたいと思います。