Visual Studio のテンプレートを使ってAWSにWebAPIを作成する

# はじめに

AWS上にWebAPIを作成するときは、VisualStudioのテンプレートを使ってAWSにデプロイすると手早く環境を構築することができます。そのやり方について色々教える機会が増えてきたのでアウトプットしました。

# 前提条件

- Visual Studio 2022 をインストール済み。
- AWS Toolkit for Visual Studio 2022 をインストール、Credentialsを設定済み。

# 作成手順

## プロジェクトの作成

Visual Studio 2022を起動し、「新しいプロジェクトの作成」をクリックします。
新しいプロジェクトの作成画面で、右上のテンプレートの検索から「C#」「AWS」を条件として選択します。
すると以下のように４つ程候補が表示されるので、今回は「AWS Serverless Application with Tests (.NET Core -C#)」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/995054f6-999b-acfc-9e3c-71d7a9f867ba.png)
プロジェクト名など必要情報を入力して作成をクリックします。今回は既定値のAWSServerless1を利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/3d85fffd-4741-bf25-5d94-e466d174fc02.png)
次のBlueprint選択画面で「ASP.NET Core Web API」を選択し、Finishをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/a47a7fbc-8d4c-e5f4-14c8-9d957afbed5d.png)
これでプロジェクトが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/bdcf3230-62dc-1337-5539-6b0026b0c10e.png)

## SAMテンプレートの修正

「serverless.template」というファイルがSAMのテンプレートファイルになります。このファイルの以下の部分を追記します。

```diff_json:serverless.template
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",
  "Parameters": {},
  "Conditions": {},
+ "Globals": {
+   "Api": {
+     "OpenApiVersion": "3.0.0"
+   }
+ },
  "Resources": {
```

これはSAMのバグでAWSへのデプロイ時に「Stage」という名前のステージが何故か作られてしまうというバグを回避するための対応になります。ただし、このバグは特に害があるわけではないので、対応必須ではありません。詳細が知りたい人は以下のリンクを参考にしてください。
<https://github.com/aws/serverless-application-model/issues/191#issuecomment-515589603>

# 動作確認：デバッグ

Visual Studioの「デバッグの開始」をクリックしてデバッグします。しばらくするとブラウザが立ち上がり、以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/20c17fec-f669-6816-dfd9-b7d069448db2.png)
サンプルのGETメソッドを確認します。表示されているアドアレスの後ろに「/api/values」を追加しEnterを入力します。すると以下のようにレスポンスが返却されることを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/fed7a343-b761-b06b-3a1a-ec9d2252bd11.png)
ソースにブレークポイントを設置するとデバッグできます。また、ブラウザからではなく、この状態でPostmanなどのツールを立ち上げ、同様のアドレスにリクエストを送信することでも評価できます。POSTなどリクエストボディのあるメソッドを評価する場合はこちらのほうが良いでしょう。

# 動作確認：テスト
Visual Studio のテストエクスプローラーを起動し、テストを実行します。サンプルではGETメソッドに対するテストが用意されています。テストコードを実装する際は、こちらのサンプルをお手本に実装を進めるのが良いでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/ee82f543-06ec-7a50-a6be-9111022e3db5.png)

# AWSへのデプロイ
続いてAWSへのデプロイを実施します。Visual Studio の AWS Explorer を表示させ、デプロイしたいアカウントの認証が完了していることを確認します。（AWS Explorerから既存のAWSリソースが確認できれば良いです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/f722d129-81f6-29a9-4626-b23316bbae08.png)
「AWSServerless1」プロジェクトを右クリックし、「Publish to AWS Lambda」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/d26b24d7-caea-6d56-dbf5-057d0ad41db6.png)
続いて、Pushlishの設定画面が表示されるので、Profileをデプロイしたいプロファイルに変更します。Stack NameはCloudformationのスタック名を指定します。今回は「test-api-stack」としています。S3 BucketはSAMテンプレートファイルの格納場所となるS3バケットを選択します。指定が終わったらPublishをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/b7a27210-7bd2-a7f5-d067-6da805746fab.png)
しばらくするとCloudformationスタックを管理する画面が表示されます。Statusが「CREATE_COMPLATE」になればAWSへのデプロイは完了しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/e9507611-c8f9-7526-5c47-8f918c4a3db2.png)

# 動作確認：AWSへのアクセス
先ほどのCloudformationスタックを管理する画面にAWS Serverless URLが表示されているのでコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/bc2f83bd-6467-4e2c-67ca-fb4b0b5a930d.png)
コピーしたURLをブラウザのアドレスバーに張り付けてアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/70d41046-c76a-208f-8d71-224581da96a2.png)
表示されているアドアレスの後ろに「/api/values」を追加しEnterを入力します。するとデバッグ時と同様、以下のようにレスポンスが返却されることを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/a5182d35-16cf-532b-a258-51fb4e3c666b.png)

# 補足：スタックの削除
スタックを削除する場合は、スタックの管理画面から「Delete Stack」をクリックすることで削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708575/e9507611-c8f9-7526-5c47-8f918c4a3db2.png)

# 補足：追加でやっておいたほうが良いもの

- csファイルをUTF-8に変更する。
    - Visual Stduioのテンプレートで自動作成されるcsファイルは何故か文字コードがShift-JISで作成されるようです。このためログ出力などを実装した際、CloudWathcLogs上で文字化けします。対策としてはcsファイルを開いた状態で「ファイル」-「名前を付けて...を保存」からダイアログを表示。プルダウンから「エンコード付きで保存」を選択し、「Unicode(UTF-8シグネチャ付き)-コードページ65001」を選択して上書き保存します。
- serverless.templateをJSONからYAMLにコンバートする。
    - Visual Stduioのテンプレートで作成されるSAMテンプレートはJSON形式です。好みになりますがYAML形式にしたい人はコンバートします。私はコメントが扱えるYAML形式のほうが好みなので変換しています。

# さいごに

今回は、Visual Studio のテンプレートからAWS上にWebAPIを構築しました。他にも便利なテンプレートが一通り用意されているので、必要に応じてテンプレートを使い分けることで、開発初期の立ち上げをスムーズにすることができます。以降、コードの実装やSAMテンプレートの修正等を行う必要がありますが、その際の注意点やポイントなどは時間があるときにまとめたいと思います。