Google Apps Scriptでお手軽にウェブサーバーアプリ開発をしてみよう

諸般の事情で、CSGの夏のAdventCalendarに参加することになったので、その15日目に該当する記事です。世間的にはいまさらGASの入門ネタですが、意外とこういうネタを学生は知らなかったりするので参考になれば。。。

## Google Apps Scriptとは
Googleが提供しているG Suite（Google Document, SpreadSheet, Slide, Forms, Drive）などで動作させることができるスクリプト実行環境です。GASという略称がよく使われています。ExcelでいうVBAみたいな位置づけになるといえばわかりやすいでしょう。実際、Google SpreadSheetと連携させることが多かったりします。さらに本日のお題で挙げているようにウェブアプリケーションを開発することもできます。言語はJavaScriptです。

## GASでウェブアプリケーションを開発する利点
### Googleのサービスとの連携が容易
現在はアプリケーションを開発する時はすべてフルスクラッチで作るより、いろんなサービスをマッシュアップしていくのが流行りというか一般的ですね。GASはG Suitesの直接的な制御のほか、Googleの各種サービス（API）と容易に連携させることができます。

- G Suite services　・・・　 Calendar, Document,Drive, Forms, Gmail, Groups, Language, Maps, Sites, Slide ,SpreadSheets
- Advanced Google services　・・・Admin, AsSense, Analytics, BigQuery, Classroom, Drive, Fusion Tables, Google+, Tasks, Tag Manager, URL Shortener, Youtube 

### 無料で利用できる
ウェブアプリケーションの開発といえば、PHPとかJava ServletとかRuby on Railsとかで実装するのが一般的かと思いますが、それらを動かして公開するにはウェブサーバーが必要です。レンタルサーバ借りる？スクリプトが動くようなサーバだとお金かかるよね。。。という話になり、学生には敷居が高くなります。一方、GASはウェブ動作環境含めて無料です。

### JavaScriptで書ける
個人的にはJavaScriptは好きではないのですが、JavaScriptはウェブのフロントエンドで使われる言語であり、習得の敷居が低いです。 GASでウェブアプリケーションを開発をするのであれば、サーバーサイドからフロントエンドまで全てJavaScriptでフォローできます。１つの言語習得でいいというのは学習コストが減ることにつながります。

##はじめの一歩
まずはSpreadSheetから起動してみましょう。別にSpreadSheetでなくても、GASのプロジェクトとして単体で起動することは可能です。ただ、（本記事では述べませんが）GASによるSpreadSheetの操作をマスターしておくと、ウェブアプリ上でのちょっとしたデータ管理が便利になります。
![Image.png](https://qiita-image-store.s3.amazonaws.com/0/35056/a3bcd365-136c-fab3-8632-495b4cb9dd6b.png)


コードgsというファイルがあると思うので、以下の関数を追加しましょう。Java Servletアプリケーションなどの開発経験があればわかると思いますが、これらの関数はHTTPメソッドに対応しています。

``` コード.gs
function doPost(e){
  //POSTメソッド用
}
function doGet(e){
  //GETメソッド用
}
```

では実際にコードを書いてみましょう。クライアント側で明示的にPOSTとしてアクセスしない限りGETメソッドが反応しますので、今回はdoGetのほうに記述します。単純に文字列を返したい場合には下記のように書きます。

``` コード.gs
function doGet(e){
  var output = ContentService.createTextOutput();
  output.append("あああ");
  return output;  
}
```

JSONを返したい場合は、MIMEタイプを指定しましょう

``` コード.gs
function doGet(e){
 var json;  //jsonのデータを格納しておく
 var output = ContentService.createTextOutput();
 output.setMimeType(ContentService.MimeType.JSON); //MIMEタイプの指定 
 output.setContent(json);
 return output;
}
```
HTMLページを返したい時は、GASの環境でHTMLページを新規作成して、それをdoGet関数の中で呼び出して返すようにします。

``` test.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    テストページ
  </body>
</html>
```
``` コード.gs
function doGet(e){
 htmlOutput = HtmlService.createTemplateFromFile("test"); //test.htmlを返す
 return htmlOutput.evaluate();
}
```
動的にHTMLの内容を生成するには、下記のようにHTML内で？タグで囲むことでスクリプトレットになります（JSPと似てますね）。スクリプトレットでは、コード.gsで定義された変数の他に関数も呼び出すことができます。下記の例では、おちという文字が出力されます

``` test.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    テストページ
    <?=name;?>
  </body>
</html>
```
``` コード.gs
var name;  //グローバル変数にしておく
function doGet(e){
  name = "おち";
  htmlOutput = HtmlService.createTemplateFromFile("test"); //test.htmlを返す
  return htmlOutput.evaluate();
}
```
ウェブクライアントからのデータの引き渡し、つまりHTTPパラメーターを受け取るには、doGetまたはdoPostの引数eのprameterから受け取ります。下記は、id というhttpパラメーターを受け取っています。

``` コード.gs
function doGet(e){
 var id = e.parameter.id;
  ＜略＞
}
```
以上、最低限のポイントを書きましたが、ウェブアプリ開発の知識があればGASでのウェブアプリ作成のやり方がと思います。なお、GASにはクライアント側のJavaScriptから、GASのサーバー側の関数を非同期で呼び出すことができる枠組み（google.script.run）があります。これを用いれば、クライアントからサーバのデータの引き渡しでさらに凝ったことができるようになります（今回は取り上げません）。


##GASでウェブアプリケーションを実装する際に不便なところ
基本的に、GASのプロジェクトの中でサーブレット的なファイル（doGetなどが書けるファイル）は１つだけです。いろいろな処理をするサーバーアプリを用意したい場合は、１つのdoGetで全てを受け取り、そこを窓口にしてパラメーターなどで処理を分けるといった工夫が必要になります。

##実行方法と注意点
ウェブアプリケーションとして実行するにはメニューの公開のところで、「ウェブアプリケーションとして導入」を選択します。
![Image.png](https://qiita-image-store.s3.amazonaws.com/0/35056/76521e14-13b6-0448-eea7-ca66e3d9e91d.png)
GASのアプリケーションはバージョン管理されていて、どのバージョンを公開するか、、といった指定をする必要があります。下記の画面が出てくるので、バージョンは新規作成にしてアプリケーションにアクセスできるユーザは「全員（匿名含む）」にしておきましょう。
![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/35056/d16707b7-f14a-28a2-929c-0b5432aa0d87.png)

そうすると下記の画面が出てきます。
![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/35056/169dc8ae-95ae-7d99-d665-86299102f0e7.png)
それ以降は、下記の画面が出ます。
![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/35056/8a029e13-9df4-c54f-e3bf-1823b790b4d9.png)

###実行時の注意点
ここが実はハマる点なので補足します。まず、公開用のURLからアクセスした場合に動作するコードは、公開用に紐付けられたバージョンのプログラムです。ソースコードだけ変えてその修正は反映されません。ですので、最新の状態を一般公開するには、上記の実行画面においてプロジェクトバージョンのところを「新規作成」にして「更新」を押してください。上の例だと、バージョン２が新たに作成されてそれが公開されることになります。
ただし、「最新のコードをテストします」のリンクをクリックすることで、更新したコードが反映された動作を確認できます。デバッグ時はそこをクリックすることをおすすめします。

##実運用にどれだけ耐えられるか
無料ですから当然利用制限はあります。詳しくは[Quotas for Google Services](https://developers.google.com/apps-script/guides/services/quotas) を御覧ください。この仕様も変わる可能では当然あることから、個人利用とか、ちょっとした内々のメンバーで試すとか、ハッカソンなどでの臨時的なサーバー開発みたいなのに向いていると思います。そういう点で学生向けとも言えます。ただ、GASを業務や自社製品に導入している会社もあります。使い方次第では強力なプラットフォームになるかもしれません。

###おわりに
今回はウェブサーバーアプリ開発をネタにしましたが、個人的にはちょっとした自作のウェブAPIを作りたいときなどは、GASがオススメかと思います。私もメール配信（Gmail API）や英日翻訳（Language API）のサービスをウェブAPI化して、自作のアプリの中で利用しています。サーバアプリの開発に関心がある学生さんはぜひトライしてください。