オリジナルKdB(科目検索)を作ってみよう -番外1- FaaS下準備編

### これまでの記事
- [オリジナルKdB(科目検索)を作ってみよう -1- Node.jsセットアップ編](https://qiita.com/tkkrr/items/2f0d93b6d0c758a88037)
- [オリジナルKdB(科目検索)を作ってみよう -2- パース編](https://qiita.com/tkkrr/items/d8a87b4f598b1b107266)
- [オリジナルKdB(科目検索)を作ってみよう -3- データで遊ぶ編](https://qiita.com/tkkrr/items/8c0f66312212420114a0)
- [オリジナルKdB(科目検索)を作ってみよう -4- Express.jsでWEBアプリことはじめ編](https://qiita.com/tkkrr/items/5cafa77c104b11d76a16)
- [オリジナルKdB(科目検索)を作ってみよう -5- Express.jsでWEBアプリ整形編](https://qiita.com/tkkrr/items/9ea97ee9b2823e3a381e)
- [オリジナルKdB(科目検索)を作ってみよう -6- 本番環境Herokuにデプロイ編](https://qiita.com/tkkrr/items/db58c25ac65da30531e9)

<img width="1241" alt="スクリーンショット 2019-02-22 16.11.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/3d0c6b57-d3a9-1be1-4166-f9068a2f9771.png">

# この記事を読む前に
ある特定の人にしかわからない単語が出現する可能性が高いです。あらかじめご了承ください。

### この記事での開発環境
- MacOS 10.14.3
- Visual Studio Code 1.31.1
- Node.js LTS 10.15.1

# はじめに
「オリジナルKdB(科目検索)を作ってみよう」の番外編です。これまではExpress.jsは使わず、**サーバレス**なシステムを作っていきましょう。シリーズでやっていたようにExpress.jsでエンヤコラはやらずに、**関数を作る**だけで簡単にサービスを作ることができます。

# FaaS について
IaaS,BaaS,PaaS,SaaSなどに連なるサービスの1つが**FaaS**(Function as a Service)です。**関数**のみを記述するだけで良く、サーバ周りの記述を省略できる画期的なサービスです。

「サーバ周りに関するコードを書かない → サーバを用意する必要がない」ことから**サーバレスアーキテクチャ**と呼ばれます(縮めて「サーバレス」と呼ばれることが多いです)。

- lambda関数を用意する。
- FaaSにアップロードする。

たった2ステップで簡単です。しかも、サーバを持たないのでDDoS攻撃によってサーバが落ちることがありません。データベースに直接接続していないため「サーバに侵入されて個人情報が...!?」というケースもありません。しかもサーバを24時間365日稼働しているわけではありません。リクエストが来た時だけ稼動するのでコストを抑えることができます。

**簡単・安全・安い**がFaaSのウリです。

# FaaSを提供しているサービス
FaaSを提供しているサービスはいくつかあります。

#### [AWS lambda](https://aws.amazon.com/jp/lambda/)
<img width="1440" alt="スクリーンショット 2019-02-28 22.13.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/09d7449d-2229-fc06-413e-c7ed4795c8ec.png">

AWS(Amazon Web Service)で提供されているFaaSです。
さすがAWSというだけあって、**毎月100万リクエスト、400,000 GB-秒まで無料**とめちゃめちゃ太っ腹です。Node.js以外に**Python, C#(.NET Core), Go, Java, Ruby**と多様な言語に対応しています。まず始めるならオススメしたいFaaSと言えます。

また、AWSが提供する他のサービスとの連携に優れており「S3(AWSの提供するクラウドストレージ)にファイルをアップロードしたら自動的に圧縮する」ような処理を簡単に組み立てることができます。

#### [Google Cloud Functions](https://cloud.google.com/functions/?hl=ja)
<img width="1440" alt="スクリーンショット 2019-02-28 22.27.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/8f3d990c-084f-55e4-6a2b-8dad2468af73.png">

GCP(Google Cloud Platform)で提供されているFaaSです。
こちらも**200万リクエスト、計算時間100万秒**まで無料と太っ腹。こちらはNode.js限定(Go, Pythonがベータ版)です。専用のライブラリを入れる必要がありますがlambda関数の書き方が簡潔であり、**日本語のレファレンスが充実**しています。

GCPの他のサービスと連携しやすいのも利点です。GCPのサービスは欲しいところに欲しい説明をくれるので、初心者から上級者まで使いこなせるのがいいですね。

#### [IBM Cloud Functions](https://www.ibm.com/jp-ja/cloud/functions)
<img width="1440" alt="スクリーンショット 2019-02-28 22.40.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/5465de24-d8d2-ff0f-5666-a565c6030994.png">

IBM Cloud で提供されているFaaSです。
使ったことがないので料金体系がわかりませんが、見た感じとても安いです。何よりも**Node10.X**や**Swift4.X, PHP 7.X, Python3.X**と、新しいバージョンに対応しているのが素晴らしいです。実行環境で最新の機能が使えるのが最高です。

#### [Zeit Now](https://zeit.co/now)
<img width="1440" alt="スクリーンショット 2019-02-28 22.48.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/bd97908e-35eb-623e-ee7c-86db5ec4415f.png">

**爆速デプロイ**をウリにしているFaaSです。料金体系がわかりやすく、個人サイト程度の規模なら**無料**で使うことができます。課金をすれば**激安定額なのに商業利用に耐えるスペック**で利用できます。また、lambda関数をアップロード時に本番環境を想定したサーバに一旦保存されるので「本番にデプロイしたら不具合が起きた！！！」なんてことを事前に検証することができます。

とりあえず完全無料でFaaSを初めてみたいという方にはオススメです。


上記の他にもいくつもFaaSを提供しているサイトがあります。自分好みなサービスを見つけてがっつり使っていきましょう💪💪

# ところで今回すること → 下準備
Lambda系のサービスに共通する特徴に**ファイル入出力周りが安定しない**ことが挙げられます。そのため、これまで使っていた`fs`モジュールでのファイル読み込みは使わないように調整しましょう。

参考記事 → [AWS Lambdaでファイル入出力をしてみる](https://qiita.com/yoshidasts/items/ba7ffc5463d7bf603ce9)

`module.exports`したファイルはちゃんと読み込んでくれるので、CSVファイルに書かれている全ての情報をjavasctiptファイルに書き出しましょう。

まずは必要なパッケージをインストールします。

```shell
$ npm install iconv-lite csv 
```

そしたら、以下のように`dump.js`を作ります。

```javascript:dump.js
const fs = require('fs');
const iconv = require('iconv-lite')
const parse = require('csv').parse;

// CSVファイル(Shift_jis)を読み込んでパース
const dataGet = () => {
    const text = fs.readFileSync("kdb.csv")
    const ret = iconv.decode( Buffer.from(text), "Shift_JIS");
    const dataArray = []
    parse(ret, (err, data) => {
        if (err) console.log(err.message)
        else {
            data.forEach( (element) => {
                dataArray.push(element)
            });
        }
    });
    return dataArray
}

// 配列をもらってJSON化
const dataToJson = async (dataArray) => {
    const dataJson = { subjects: [] }
    dataArray.forEach( (element) => {
        dataJson.subjects.push( 
            {
                id: element[0],
                name: element[1],
                lessonType: element[2],
                credit: element[3],
                level: element[4],
                semester: element[5],
                period: element[6],
                place: element[7],
                teachers: element[8],
                summary: element[9],
                remarks: element[10],
                otherCourseStatus: element[11],
                otherCourseInfo: element[12],
                engName: element[13],
                engId: element[14],
                searchOption: element[15],
                timestamp: element[16],
            }
        )
    })
    return dataJson
}

// 即時関数でdata.jsを生成
(async () => {
    const data = await dataGet()
    const json = await dataToJson(data)
    const myJs = `const json = ${JSON.stringify(json)};
module.exports = json;`
    fs.writeFileSync("data.js", myJs)
})()
```

※async/awaitについて説明してると記事が爆発的に大きくなってしまうので割愛します。
async/awaitについての参考サイト(`Promise`と一緒に覚えると楽です)

- [async await の使い方](https://qiita.com/niusounds/items/37c1f9b021b62194e077)
- [async function | MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)
- [Promiseのメソッドチェーンの使い方まとめ](https://qiita.com/naoto_koyama/items/7234d133f0d5f87532db)

実行して、新しく`data.js`が作られていることを確認しましょう。

```shell
$ node dump.js
$ ls
dump.js               kdb.csv         package.json
package-lock.json     node_modules    data.js
```

`data.js`の中身をみればわかりますが、`kdb.csv`の情報が全て書き出されていることがわかります。もしうまく書き出せていなかったら、ごめんなさい...コメントにお願いします。

# とりあえず今回はこの辺で
下準備だけで内容のない記事となってしまいましたが、次回からがっつりFaaSを使っていきますので許してください。
ちなみに、AWSとGCPの2つを触る予定です。

- [AWS Lambda編](https://qiita.com/tkkrr/items/e67227bcb15c1a08bb2b)