AzureにNode.jsから画像を保存する 準備編


画像の保存などをやりたいなと思ってAzureでやってみよ〜と思った時の話です。

## まずは情報に行き着くまでが大変でした

Azureに限らずAWSもGCPもそんな感じだとは思いますが、サービス多いので概念理解をするのに時間がかかるといったやつです。

### Azureに画像を保存したいけどBlobストレージとかFilesとか調べるとごちゃごちゃ...

って感じです。 

調べるとAzureのBlob Storageというサービスが画像とか保存できるっぽい話が出てきます。ただAzure Filesってのも出てきたり、なんかもっと色々出てきます。 ~~少しイラつき。笑~~

[Azule Filesとは](https://docs.microsoft.com/ja-jp/azure/storage/files/storage-files-introduction#why-azure-files-is-useful)とかを調べてみて雰囲気こんなかなぁという印象が

- Azure Blob Storage => API経由で利用想定
- Azure Files => NASとか社内共有フォルダ的な利用想定（APIもある）

といった印象。

とりあえずBlob Storageの方を使ってみます。

### ポータルからblobって調べるとストレージアカウントというまた新ワードが出てくる

割と分からんけど、これかなぁ、、という感じで進めてみたけど合ってたみたい。

> ![スクリーンショット 2021-09-06 9.39.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/faaaf896-3b29-5e3f-bb4b-39549584b3ef.png "スクリーンショット 2021-09-06 9.39.47.png")


今だによく分かってはないけど使えたのでよしとします。

（きっとこの記事をみた詳しい人が教えてくれるはず！）

と言うかうんじで`ストレージアカウント`なるものを作成します。この時の気持ち的にはストレージを使いたいのにアカウント作るのか？という雰囲気。

> ![スクリーンショット 2021-09-06 9.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/32c2df62-9492-fa5d-1622-565fcf505d12.png "スクリーンショット 2021-09-06 9.44.56.png")

こんな感じで作ってみました。

> ![スクリーンショット 2021-09-06 9.46.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/0226e6f7-d3b6-13b5-48f0-a8f00888e3ef.png "スクリーンショット 2021-09-06 9.46.26.png")

プレミアムって表記もありますが、とりあえずStandardで。

>![スクリーンショット 2021-09-06 9.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/82b580a2-652f-01b3-31bb-9a4cd77a2dcd.png "スクリーンショット 2021-09-06 9.54.27.png")

作成してリソースグループに移動するとこんな感じの画面になります。

## Azure Blob StorageをNode.jsから利用する

とりあえずリソースは作ったっぽいけど、どう使うんだということで調べてたらSDKを見つけました。

[Azure/azure-sdk-for-js](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/storage/storage-blob/samples/javascript)こちらのサンプルを触ってみます。

### どのキーを使うのか

[basic.js](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/samples/javascript/basic.js#L15-L16)を見ると、`ACCOUNT_NAME`と`ACCOUNT_KEY`を入れたら使えるっぽい雰囲気があるので調べてみます。

どうやらこれらっぽいですね。キーの表示を押すとキーが表示されます。

> ![スクリーンショット 2021-09-06 9.52.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ab2d9b9a-eaaa-9cd1-653b-1c33634aa620.png "スクリーンショット 2021-09-06 9.52.29.png")

[basic.js](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/samples/javascript/basic.js#L15-L16)を試してみました。

```bash
$ npm i @azure/storage-blob
```

dotenvは使わないので[11行目](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/samples/javascript/basic.js#L11)は削除して試します。

```bash
$ node basic.js

Create container newcontainer1630887559036 successfully e5e72525-101e-0037-7eb4-a27f37000000
Upload block blob newblob1630887559208 successfully e5e72597-101e-0037-6bb4-a27f37000000
Blob 1: newblob1630887559208
Downloaded blob content hello
deleted container
```

ほうほう... サンプルコードで何行われてたかコード読まずに実行（危ないw）したけどどうやら、`コンテナってのを作る -> データをアップロードする -> データのダウンロードをする -> コンテナを消す` みたいな雰囲気で処理をとりあえず実行しましたよってサンプルっぽいですね。

とりあえずsuccessっぽい挙動なのでとりあえずキーなどは合ってた模様。

### Azure Blob Storageにコンテナを作成する

とりあえず先程のコードだとコンテナ作成して削除してまでをやってるので、とりあえずコンテナ作成部分だけ抜き出して見ました。

名前も`n0bisuke-container~~`的な名前にしてみます。

```cc.js
'use strict';

const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");

async function main() {
  // Enter your storage account name and shared key
  const account = process.env.ACCOUNT_NAME || "ストレージアカウント名";
  const accountKey = process.env.ACCOUNT_KEY || "キー";

  const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
  const blobServiceClient = new BlobServiceClient(
    `https://${account}.blob.core.windows.net`,
    sharedKeyCredential
  );

  //コンテナの作成
  const containerName = `n0bisuke-container${new Date().getTime()}`;
  const containerClient = blobServiceClient.getContainerClient(containerName);

  const createContainerResponse = await containerClient.create();
  console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);

}

main().catch((err) => console.error("Error running sample:", err.message));
```

実行してみます。

```js
$ node cc.js

Create container n0bisuke-container1630888214169 successfully 947cbed6-101e-0027-7bb6-a2ba5f000000
```

お、成功したっぽい。

管理画面を見ると指定した名前の`コンテナー`が表示されてました。

> ![スクリーンショット 2021-09-06 10.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/3c0857d7-6ade-e8e9-4b38-ff0d104a1a4a.png "スクリーンショット 2021-09-06 10.04.23.png")

まだ`コンテナー`が何なのか分かってないですが多分大枠のフォルダみたいな概念だと思っておきます。

### 作成したコンテナにアクセス

`cc.js`を一部変更して`show.js`を作ってみました。

```show.js
省略

  //コンテナを作成した名前に指定
  const containerName = `n0bisuke-container1630888214169`;
  const containerClient = blobServiceClient.getContainerClient(containerName);
  console.log(containerClient);

省略
```

実行するとコンテナの情報が表示されました。

```bash
$ node show.js

ContainerClient {
  url: 'https://xxxxxxxxxxxx.blob.core.windows.net/n0bisuke-container1630888214169',
  accountName: 'xxxxxxxxxxxxxx',
  pipeline: Pipeline {
    factories: [
      [Object],
      
省略
```

### コンテナにデータをアップロードしてみる

この辺までくると割とイメージ掴めてきました。
basic.jsにあったコードを持ってきてアップロード出来ました。
basic.jsで既にやってた処理ですけどね。

> 参考: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/samples/javascript/basic.js#L62-L66

```upload.js
省略

  //コンテナを作成した名前に指定
  const containerName = `n0bisuke-container1630888214169`;
  const containerClient = blobServiceClient.getContainerClient(containerName);
  
  // Create a blob
  const content = "hello";
  const blobName = "newblob" + new Date().getTime();
  const blockBlobClient = containerClient.getBlockBlobClient(blobName);
  const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
  console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
  

省略
```

実行するとこんな感じでポータル上にも表示されます。

> ![スクリーンショット 2021-09-06 10.16.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/cfeb1687-9348-56f6-d85f-91c27b63e29d.png "スクリーンショット 2021-09-06 10.16.06.png")

何か出来てますね。このNode.jsのコード見る限りだと`hello`って文字列が入ってそうです。

> ![スクリーンショット 2021-09-06 10.21.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ec31cc45-5afc-a28d-85e5-8cb4fa2eeaaa.png "スクリーンショット 2021-09-06 10.21.07.png")

5Bって書いてるしそれっぽいですね。

### いよいよ画像を投稿

長くなってきたのと、この辺は分かってる人は見なくてもよさそうということで、記事を分けて[次回](https://qiita.com/n0bisuke/items/2192c1acf0be73398e2b)に続く...