Node.js + Express + App Service(Azure)でAPIサーバーを作る

## はじめに
WebAPIのテスト用のサーバーがほしいので作ってみた。
「Node.js + Express + App Service(Azure)」 の構成で作ります。
レスポンス値を変更したときにデプロイするのは面倒くさいので、gitへのpushをキーにデプロイするようにします。

## 作ろうと思った経緯
ローカルテスト環境がなく、お客さんに許可を取らないと（他の会社さんが作っている）WebAPIを含む機能のテストができない。
許可申請から承認が下りるまでに1週間かかり、その間は待機しているらしい。
テスト用のダミーサーバーを作って試験を進められるようにしたい。  

## 前提条件
* nodeのインストール済（検証環境はnodistインストール済だった）
* Azureのサブスクリプション、リソースグループは作成済

## 検証環境
* Windows10
* VSCode 1.42.1
* nodist: 0.9.1
* node: 10.15.3
* npm: 6.9.0

## とりあえずローカルで作ってみる
Azureのチュートリアルに沿って作成すればOK。
* [クイック スタート: Node.js Web アプリを作成する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-web-get-started-nodejs)
以下からのコマンドは、VSCodeのターミナル（bash）で実施している。

### てきとうなディレクトリを作成し、移動する

```
cd azure-app-service
```

### expressプロジェクトの作成

#### コマンド
```sh
npx express-generator myExpressApp --view pug --git
```

#### 実行結果
```console
$ npx express-generator myExpressApp --view pug --git
npx: 10個のパッケージを20.703秒でインストールしました。

   create : myExpressApp\
   create : myExpressApp\public\
   create : myExpressApp\public\javascripts\
   create : myExpressApp\public\images\
   create : myExpressApp\public\stylesheets\
   create : myExpressApp\public\stylesheets\style.css
   create : myExpressApp\routes\
   create : myExpressApp\routes\index.js
   create : myExpressApp\routes\users.js
   create : myExpressApp\views\
   create : myExpressApp\views\error.pug
   create : myExpressApp\views\index.pug
   create : myExpressApp\views\layout.pug
   create : myExpressApp\.gitignore
   create : myExpressApp\app.js
   create : myExpressApp\package.json
   create : myExpressApp\bin\
   create : myExpressApp\bin\www

   change directory:
     $ cd myExpressApp

   install dependencies:
     $ npm install

   run the app:
     $ DEBUG=myexpressapp:* npm start

```

### npmインストール
#### コマンド
```sh
cd myExpressApp
npm install
```

#### 実行結果
```console
$ npm install
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN lifecycle The node binary used for scripts is C:\Program Files (x86)\Nodist\bin\node.exe but npm is using C:\Program Files (x86)\Nodist\v-x64\10.15.3\node.exe itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed 
with.

> core-js@2.6.11 postinstall C:\workspace\azure-app-service\myExpressApp\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)

npm notice created a lockfile as package-lock.json. You should commit this file.
added 118 packages from 174 contributors and audited 247 packages in 18.009s
found 1 low severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details
```

### サーバー起動
ここまでexpressプロジェクトができているので、サーバーが起動できる。  

#### コマンド
```sh
npm start
```

#### 実行結果
```console
$ npm start
npm WARN lifecycle The node binary used for scripts is C:\Program Files (x86)\Nodist\bin\node.exe but npm is using C:\Program Files (x86)\Nodist\v-x64\10.15.3\node.exe itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed 
with.

> myexpressapp@0.0.0 start C:\workspace\azure-app-service\myExpressApp
> node ./bin/www


```

### ブラウザで確認
ブラウザで `localhost:3000` にアクセス。  

<img width="1058" alt="001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/2a200301-157b-f519-8576-b8b893bfc73f.png">


動いているのが確認できた。  

## AzureでAppServiceを作成する

### AppServiceを作成する
AzurePortalを開く。  

* [ホーム - Microsoft Azure](https://portal.azure.com/#home)

追加をクリック。  
<img width="914" alt="002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/9feb70c8-29aa-9254-dc3d-3d41446d4804.png">

### サービスの設定
各項目を入力する。  
<img width="615" alt="003.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/951c79c7-0c6e-9fab-478a-03c08c45e7c3.png">

* サブスクリプション：事前に用意したもの
* リソースグループ：事前に用意したもの
* 名前：任意。ここの入力名がURLの1部になる
* ランタイムスタック：今回はnodeを使うので、最新の「Node 12 LTS」にした
* 地域：とりあえず東日本
* SKUとサイズ：初期値はいい感じのスペックのものにされているので、1番安価な「F1」に変更

入力したら「確認および作成」を押下 → 確認画面に遷移するのでそのまま「作成」  

問題なければ、デプロイが開始される。  

1分くらいでデプロイが完了する。
<img width="1051" alt="004.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/afebe25c-4ef1-91b8-8f05-a10680c38f41.png">

## 自動デプロイの準備

### githubでデプロイ用のリポジトリを作成する
自分は、「azure-app-service」を作成した。  

### ローカルにクローンする
任意の場所に先ほど作成したリポジトリをクローンする。  

### 資材の移動
ローカルでの検証時に作成した「myExpressApp」の中身をリポジトリの直下にコピーする。

### 移動後のディレクトリ構成イメージ
<img width="630" alt="006.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/ea9878db-591a-0f1c-a795-49c9c3495d73.png">

### 動作確認
この状態で動くか確認する  

```
npm start
```

して

`localhost:3000`

に接続してExpressの画面が出ればOK  

### コミット
動作が確認できたので、念のためこの状態でコミット→プッシュしておく。

## Azureにデプロイする

「自動デプロイの準備」で作成したプロジェクトをVSCodeを開く。  

### 拡張機能をインストール
Azure App Serviceを操作するための、拡張機能「Azure App Service」をインストールする。 
 
* [Azure App Service - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice)

インストールが完了すると左部のメニューに追加されるので選択する。 
<img width="223" alt="005.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/ee6a1277-f675-1c46-8056-7130c48ede74.png">

### 上部の「↑」を選択
上部の「↑」（Deplay To Web App...）を選択する。  

* Select the folder to zip and deploy: Expressプロジェクトのルートディレクトリを選択（azure-app-service）
* Select subscription: AppServiceを作成したサブスクリプション
* Select Web App: 作成したAppServiceを選択
    * 上書きしてよいか確認ダイアログが出るので、「OK」→「Deploy」

デプロイが始まるので、完了するまで待つ（10秒くらい）。  

### デプロイが完了したら実際に接続してみる

「https://<作成したAppService名>.azurewebsites.net/」にブラウザで接続  

デプロイができていれば下記のようにローカルと同じ画面が出る。
<img width="1058" alt="007.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/528e7d2e-18e0-bb12-d5d1-be43aa9f10c6.png">

これでデプロイはOK。  

## Azureに自動デプロイする

### デプロイ設定を行う
AzurePortalで作成したAppServiceを開き、画面左部メニューから「デプロイセンター」を選択する。  
<img width="921" alt="008.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298626/b4f16534-8031-4110-919c-a88de049e50c.png">

### デプロイ設定

1. ソース管理：Githubを選択（初回は認証がかかるかも）
2. ビルドプロバイダー：App Serviceのビルドサービス
3. 構成：
    * 組織：自分のgithubアカウント
    * リポジトリ：作成したリポジトリ
    * ブランチ：master
4. 概要：内容を確認して、完了を押下

デプロイ設定もこれで完了。  
今後はmasterブランチにプッシュされたタイミングでビルドが走るようになる。  

## （参考）作業を行ったgithubリポジトリ
* https://github.com/aky100200/azure-app-service.git

## おわりに
今回はじめてwebサーバを作成したが、こんなにも簡単にできるんだという感想。
自分は今までプログラミングがメインでAzureを使ったり、サーバを構築したりという作業をしたことがなかった。
作ったものが自分のPC内だけで動いているのと、全世界からつながっているのはやっぱり感動が違う。
今回はテスト用のレスポンスサーバーが目的だったが、Webサービスも簡単に作れるようになっているのはすごいと思った。
Webサービスを公開する予定はないが、このように簡単に構築できることを知れて良かった。