知識の無い新卒がNext.jsとASP.NET CoreでTodoアプリを作成しコンテナ化したお話

こんにちは、新卒のますだです。※あだ名は絶賛募集中です:cry:
本記事は[弥生 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/yayoi)の12日目の記事になります。
12/12とバランスが良かったのでこの日を選びました。

一か月ちょっとでTodoアプリを作成しました。
「どういった流れで新しい技術を学び、成果物を作成したのか」
について当時のますだの心情と共に、簡潔に書いていきたいと思います。
温かい目で見て頂けると幸いです。

#簡単な自己紹介

* 2020年に弥生に新卒として入社

* 基本的なjavaの知識はある

* 楽観的でポジティブ

[mgram](https://mgram.me/ja)では「異常に怖いもの知らず」という診断結果がでました。
また、[mgram](https://mgram.me/ja)は入社直後と入社半年後で二回診断したのですが、
運命の人と出会う確率が1/3188から1/10235に下がったので、結婚願望が強い人は仕事をしない方が良いと思いました。

#上司からの依頼（トレーニング内容）

1. Next.jsだけを使ってTodoアプリを作成せよ！（Visual Studio Codeで作成）

2. ASP.NET Coreでバックエンドサービスを作成せよ！！（Visual Studioで作成）

3. 1と2で作成した成果物を繋げよ！！！

4. 3で作成した成果物をDockerでコンテナ化せよ！！！！（Visual Studio Codeで作成）

**要件：**
　・タスク一覧が見られること
　・タスクが追加・編集・削除できること
　・タスクは以下の項目を持つこと。タスク名・詳細・期日・完了フラグ
　・作成した成果物はgitLabにあげよ。

##ますだの心情

* gitってどう使うんだっけ...

* Next.js...?

* ASP.NET Core...??

* 繋げる...???

* Docker...????

「??????????????????????」と脳内は？だらけでした。

#Next.jsとASP.NET Coreとdockerを簡単に説明
* Next.js

 * [ZEIT社](https://vercel.com/)によって開発されたJavascriptのフレームワーク

 * [React](https://ja.reactjs.org/)のSSR・SSGを実現。簡単にいうと、ブラウザ上ではなくサーバー側でデータをレンダリングし、HTMLファイルを表示する。

 * メリット
     * サーバー側でレンダリングするためコンテンツの表示が早い

     * SEOの向上

     * ルーティングが楽　など

* ASP.NET Core

 * [マイクロソフト社](https://www.microsoft.com/ja-jp/)が提供しているWebアプリケーション開発フレームワーク

 * マルチプラットフォーム（Windows,Linux,Mac）で動作する.NET環境

 * メリット

     * OSに依存せず開発できる

     * WEBブラウザで表示できるためデバッグが楽　など

* docker
 * [Docker社](https://www.docker.com/company)によって開発されたコンテナ型の仮想環境を作成、配布、実行できるプラットフォーム
 * ユーザーが作成した環境やソースコードなどをパッケージ化（コンテナ化）することができる。
　コンテナ化したものは他のパソコンで実行することが可能

 * メリット：
     * ユーザーが開発したアプリケーションを環境構築せずに実行できる
     * メモリやディスクの消費量を少なく抑えた状態で仮想化するため、立ち上げるスピードが速い

#作成した成果物
* 実際のアプリケーション
※今回はトレーニングでTodoアプリを作成したためcssは無視しています。
![training.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887561/7a243473-8c0f-47c1-bc84-c5267df88952.gif)





* 以下の画像はTodoアプリの繋がりを示しています。

 * トレーニング1．Next.jsだけでTodoアプリを作成の全体図: ![Next.js.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887561/20a4633a-ca2d-7d9b-5d82-5e8af48ee585.jpeg)

 * トレーニング2．3. 4. Next.jsとASP.NET CoreでTodoアプリを作成の全体図: ![ASP.NET CoreとNext.js.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887561/38530a09-8723-0be6-ba02-75893755f0a0.jpeg)

* 成果物を作成した基本的な手順は

1. 公式チュートリアルをプレイ
2. パワーポイントで実装のイメージを書きだし検証
3. 検証した内容を上司に見せる
4. 実装
5. レビュー
です。
※手順や検証は我流です

##トレーニング1. Next.jsだけを使ってTodoアプリを作成せよ！

 * まずはNext.jsの[公式チュートリアル](https://qiita.com/thesugar/items/01896c1faa8241e6b1bc)(英語が読めないため日本語訳サイト)をプレイ<br>
      ますだ「なるほど、こういう動きをするのか。」（体感進捗率：10%）
 * 次は実装する前にtodoアプリの検証<br>
      ますだ「一文字も書けん:scream:」（体感進捗率：5%）
 * 一文字も書けなかったため、[Next.jsでtodoアプリを作成しているサイト](https://qiita.com/hiraike32/items/71b14755f56208a8a133)のコードを理解<br>
      ますだ「todoアプリを作成できそうだ:smile:」（体感進捗率：10%）
 * 再度todoアプリの検証<br>
      ますだ「DB的な役割を持つファイル(todoList.js)はどうやって作成すればいいんだ...:cold_sweat:」（体感進捗率：5%）
 * 上司の方に相談<br>
      Uさん「[API Routes](https://nextjs.org/docs/api-routes/introduction)を使用し、サーバー側でtodoの値を保持しよう！API Routesを使えばトレーニング3. にも活かせるはず」<br>
      ますだ「API Routesを使うのか。よし勉強だ!!:muscle:」（体感進捗率：10%）
 * API Routesの基本的な動きが分かったため再度todoアプリの検証 ※[1]ここでのの検証内容<br>
      ますだ「いけそうかも:yum:」（体感進捗率：50%）
 * todoアプリを実装<br>
     ますだ「うごいたぞ！:sunglasses:」（体感進捗率：80%）
 * ここで上司の方にレビュー依頼<br>
      Uさん「[CRUD](http://e-words.jp/w/CRUD.html)のDELETEにbodyはNG。queryを使用しよう！」<br>
      ますだ「:fearful:」（体感進捗率：20%）
 * DELETEにbodyではなくqueryを持たせるために[ダイナミックルーティング](https://Next.js.org/docs/routing/dynamic-routes)を使用して再度実装※[2]ここでのの検証内容<br>
      ますだ「できだ:japanese_goblin:」（体感進捗率：100%）


※[1]ここでの検証内容
![[1].jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887561/13b90cd5-76a8-2512-7a5e-6bd1c9913667.jpeg)

※[2]ここでのの検証内容
![[2].jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887561/d7521218-469c-e9c9-0e50-bc99045758f1.jpeg)


##トレーニング2. ASP.NET Coreでバックエンドサービスを作成せよ！！

 * まずは[公式のチュートリアル](https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio)（日本語版の公式チュートリアルはコードが載っていない部分が多いため英語版を推奨）<br>
     ますだ「チュートリアルの内容がtodoアプリの作成だと...ありがてぇ:joy:」<br>
     ますだ「Visual Studioが自動で色々と作成してくれる...賢けぇ:innocent:」（体感進捗率：30%）
 * 大体の流れは掴めたため検証に入る<br>
     ますだ「公式チュートリアルの内容を少し変えるだけで動きそうだ:smirk:」（体感進捗率：50%）
 * いざ実装。動作の確認は[Postman](https://www.postman.com/)を使用<br>
     ますだ「動いた...Postmanすごく便利:two_hearts:」<br>
     ますだ「Visual Studioが勝手にコードを書いてくれたから達成感が無い:innocent:」（体感進捗率：100%）

##トレーニング3. 1と2で作成した成果物を繋げよ！！！

 * まずは[公式のチュートリアル](https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/web-api-javascript?view=aspnetcore-3.1)をプレイ<br>
     ますだ「Visual Studioを使用し、Javascript(front)とASP.NET Core(backend)を繋げる方法は分かった:neutral_face:」<br>
     ますだ「が、Next.js(front)はVScodeを使用している...どうすればいいんだ:tired_face:」（体感進捗率：10%）
 * ますだの力ではGoogle先生だけで解決することができなかったため、Uさんに相談<br>
     Uさん「Next.jsはVScode、ASP.NET CoreはVisual Studioで動かせます。」<br>
     ますだ「そんなことできるのか...:flushed:」（体感進捗率：30%）
 * Visual Studioでbackend（ASP.NET Core）を起動し、起動したURIにリクエストを投げれば動いた

```javascript:todo.js
//todoを追加する処理
const uri = "<Visual Studioで起動したuri>";
case "POST":
      await fetch(uri, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        body: todoJson,//追加したいtodo
      }).catch((error) => console.error("Unable to add item.", error));
      res.status(200).json(todoJson);
```

 * 無事Next.jsとASP.NET Coreを繋げることができたが、期日が未入力の時だけうまく動かない<br>
     ますだ「エラーもでねぇ...デバッグしまくるしかねぇ...:astonished:」（体感進捗率：30%）
 * デバッグした結果、C#(ASP.NET Core)が期待通りに動いていないことが分かった。原因はC#のdate型<br>
     ますだ「どうやらC#は特殊な宣言(Null許容型)をしないとdate型にnullが入らないらしい:weary:」（体感進捗率：80%）

```c#:TodoItem.cs
//型の後ろに？を付けるとNull許容型になるらしい
public DateTime? Date { get; set; }
```
 * 数多の困難を乗り越え無事に実装完了<br>
    ますだ「:sob:」（体感進捗率：100%）


##トレーニング4. 3で作成した成果物をDockerでコンテナ化せよ！！！！
 * いよいよ最後のトレーニング。まずは恒例の[公式チュートリアル](https://docs.docker.jp/get-started/index.html)（日本語翻訳）を読む<br>
     ますだ「いや、まったく分からん:innocent:」（体感進捗率：0%）
 * とりあえず[マイクロソフトのドキュメント](https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/docker/visual-studio-tools-for-docker?view=aspnetcore-3.1)を参考にコンテナ化を試みる<br>
     ますだ「Visual Studioが賢すぎて勝手にコンテナ化できてしまった...:innocent:」（体感進捗率：3%）
 * 仮想化の概念も分からないため噛み砕いて説明してる動画をyoutubeで視聴<br>
     ますだ「これが...無料!?:anguished:」（体感進捗率：20%）
 * Dockerを抽象的に理解したため検証に入る<br>
     ますだ「...:innocent:」（体感進捗率：2%）
 * ここで相談役のKさんに自分の理解を伝えた。Kさんと話す中でDockerの理解がどんどんと深まった<br>
     ますだ「お忙しい中何度も助けて頂き、感謝感激雨霰です:zap:」（体感進捗率：50%）
 * 今度こそDockerをそこそこ理解できたため検証し、実装に入る<br>
    ますだ「書ける、書けるぞ！！:laughing:」（体感進捗率：80%）
 * VScodeでNext.jsとASP.NET Coreをコンテナ化（docker-compose）しようと試みたが期待通りに動かない。
どうやらASP.NET Core側でエラーが起きている。<br>
     ますだ「Visual Studioに自動で作成して頂いた箇所がうまく動かない...Visual Studioに頼りすぎは良くない:persevere:」<br>（体感進捗率：50%）<br>
 * Kさんのお力添えもあり、なんとかエラーの原因を突き止めた。どうやらbuildするときの階層が違ったらしい。<br>
     ますだ「Visual StudioでDockerを実行すると自動で階層を指定してくれるらしい...:disappointed_relieved:」（体感進捗率：70%）

```yml:docker-compose.yml
//VScodeではDockerfileがある階層をしっかりと指定してあげる
build:
      context: backend/SampleApi
```
 * うまくビルドできた！！が、todoアプリがうまく動かない。色々と調査し、
backend(ASP.NET Core)のコンテナとfront(Next.js)のコンテナを繋ぐネットワークの作成が必要と考えた<br>
     ますだ「世の中うまく進まねぇ...:sweat_smile:」（体感進捗率：50%）
 * 自分で実装する前に、Kさんに自分の理解を伝えた<br>
     ますだ「ネットワークを作成する必要がありますよね??:sweat:」<br>
     Kさん「[host.Docker.internal](https://docs.docker.jp/docker-for-windows/networking.html)を使えばそんなことしなくてもいけるはず」<br>
     ますだ「:flushed:」（体感進捗率：80%）
 * host.Docker.internalを使用し、いざ実行！<br>
     ますだ「う、うごいた:sob:」（体感進捗率：100%）

#さいごに
ここまで読んで頂きありがとうございました。
これがますだの一か月ちょっとの奮闘記でした。
ITリテラシーが低く苦労した点はたくさんありましたが、
周りの方に支えられ、なんとか動くものを作り上げることができました。
お忙しい中、質問に答えて頂きありがとうございました。特にUさんとKさんにはとてもお世話になりました！
今後はこの経験を活かし、新しい技術をどんどん取得していきたいと考えています！

明日の記事は[naoya_kimura](https://qiita.com/naoya_kimura)さんの「Visual Studioのパフォーマンスプロファイラーを使ってみた」です。私のフレッシュな記事とは違い、とても綺麗でわかり易い文章になってました！
お楽しみに！