DMMのGo言語5daysインターンが最高すぎた！

初めて企業のインターンに参加しました。DMMさんのGo言語5daysのインターンです。今回はこのインターンの内容、またGo言語でのAPI開発で学んだTipsを中心に記事を書きます。
温かい目で見てくださると嬉しいです。記事の内容に誤りがあった場合は、いつでもご指摘ください 🙇‍♂️

## インターン概要

今回のインターンは8月5日から8月9日の5日間にわたって行われました。最終日はオフィス開催で、4日間はオンライン開催でした。
初日と2日目は主にライブラリの使い方を学び、残りの3日間はハンズオンでAPIのエンドポイントを実装しました。このインターンの教材はDMMさんの新卒バックエンド研修の課題として使用されているため、難易度はとても高かったです。

私はGo言語を使用した経験がありますが、本で独学という勉強の仕方だったので、少し古い情報で学んでいたこともあり、今回のインターンで最近のバージョンに追加された機能などを知ることができました。また、Go言語の勉強だけでなく、アーキテクチャやライブラリの選定理由なども紹介があり、とても実践的な内容でした。

## サポート体制

開発は難しかったものの、初日から最終日まで手厚いサポートを受けることができました。インターン参加者は私を含め16名でしたが、メンターの方がインターン生の半数以上いたため、いつでも質問することができました。質問の際には画面を共有し、ペアプログラミング形式でサポートを受けることができたため、とても勉強になりました。

## 開発内容

インターンでは、Xのようなテキストを投稿できるWeb APIサーバ 、**Yatter**を実装しました。このYatterは、「八咫烏（やたがらす）」から名前を取っているのだとか。課題は、アカウントを作成するエンドポイントのみが実装された状態から追加でエンドポイントを実装していくものでした。

すでにある実装やインターン用のドキュメントを参考にしながら、テキストを投稿するエンドポイントやタイムラインを取得するエンドポイントを実装しました。
さらに、私はたどり着けませんでしたが、フォロー・フォロワー機能の実装やテスト作成、CI導入など盛りだくさんな内容でした。

特に勉強になった点が以下です。（自分があまりにもにわかGopherだと痛感しました😂）

- `json.Marshal`と`json.Encoder`の違い、`json.Marshaler`インターフェースを実装している場合、その型が独自にJSONに変換される方法を提供できること
- DBでは `NOT NULL`制約が推奨されること、難しい場合は `COALESCE` 関数で対応するのが適切であること
- ORMで何を選択するかというデファクトスタンダードはなく、プロジェクトに応じて検討すること
- `context`パッケージの使用において、闇雲にデータを入れてしまうと、引数として受け取る関数で何を受け取るか分からなくなってしまうので、使い所が重要であること

## Go言語で学んだTips

### 1. `go imports`

これまで`go fmt`を使用してフォーマットを行っていましたが、今回のインターンで新たに学んだのが、`go fmt`にさらなる便利さを加えた`goimports`です。

`goimports`は、コードをフォーマットするだけでなく、不足しているインポートを自動的に追加し、使用していないインポートを削除してくれるツールです。コードを書いていると、インポートを手動で管理するのが煩わしく感じることがありますが、`goimports`を使うことで心配ご無用に！

実際に使用してみると、コマンド一つでコードが自動的に整形され、同時にインポートの整理まで行ってくれるので、感動しました 😭 まだ使用したことがない方は、Goの開発環境をよりスムーズにするために、ぜひ取り入れてみてください。

### 2. Airの活用

Airは、ファイルの変更を監視し、何かしらの処理を自動的に実行するタスクランナーです。具体的に言うと、Goファイルを編集して保存すると、Airが自動的にその変更を検知し、アプリケーションを再起動してくれます。これは、ReactやVue.jsといったフロントエンドフレームワークで使われるホットリロードに似た機能を提供しています。これにより、手動でビルドやサーバーの再起動を行う必要がなくなり、開発スピードが格段に向上します。今までフロントエンドのホットリロードいいなあとずっと思っていたので感動しました 😭  
自分のプロジェクトにも導入してみましたが、本当に手軽だったので記事を書きました！詳細は、[こちらの記事](https://qiita.com/shio-42/items/9962cc84e8d205218d52)を見てくださると嬉しいです！

Airを使用することで、コードの変更に集中し、効率的に作業を進めることができます！

### 3. Goのテストに関するTips

テストコードを書く際に役立つツールを教えていただいたので紹介します。

- [moq](https://github.com/matryer/moq): インターフェースのモックを自動生成します。手動でモックを作成する手間が省け、エラーの発生も減ります
- [go-sqlmock](https://github.com/DATA-DOG/go-sqlmock): データベース操作のモックを作成するツールです。SQLクエリのテストをデータベースに依存せず行えるため、安定したテストが可能です
- [Table Driven Tests](https://go.dev/wiki/TableDrivenTests): 複数のテストケースを一つのテスト関数で管理できる手法です。テストケースが増えてもコードが煩雑になりにくく、シンプルかつ読みやすいテストコードを実現します。ただし、万能ではなく、アンマッチな場合もあるとのことでした

### 4. `golangci-lint`

Go言語の開発では、静的コード解析を活用してエラーを未然に防ぐ文化が根付いています。静的コード解析は、プログラムを実行することなくコードを解析し、潜在的なエラーや品質の問題を早期に発見する手法です。golangci-lintは複数のリンターを一括で実行でき、コードのバグやパフォーマンス問題を早期に発見し、メンテナンスしやすい状態を保つためのツールです。


### 5. レイヤードアーキテクチャと責務分離

ここまで開発のTipsが多かったですが、レイヤードアーキテクチャのコードの責務分離についても取り上げます。Yatterはレイヤードアーキテクチャの考え方 を取り入れています。
※今回のインターンで扱う教材は、5日間の開発期間にあわせて縮小・簡略化されたものです。厳密には違う内容が含まれている可能性があります。
 

- **DAO（Data Access Object）**: データの永続化を担当し、データベース操作を管理します。DAOはビジネスロジックを持たず、ビジネスロジックとデータアクセスロジックが分離されているため、変更が容易です。

- **Usecase**: ビジネスロジックの具体的な実行を担当します。アプリケーションのコアとなるエンティティ（ビジネスルールを持つオブジェクト）を操作し、その結果を`handler`に提供します。`usecase`はデータ操作とユーザーインターフェース間の橋渡し役として、ビジネスロジックを具体的に展開します。

- **Handler**: ユーザーリクエストを受け取り、適切な`usecase`を呼び出します。`handler`は直接ビジネスロジックに触れず、`usecase`インターフェースに依存することで、リクエスト処理とビジネスロジックを分離しています。

- **Domain**: アプリケーション全体のビジネスルールやエンティティを管理します。他の層から直接変更されることがなく、一貫性を維持します。

インターフェースに苦手意識がありましたが、実装を通して構造体がインターフェースを実装するということがどういうことか理解することができました。

コードの責務においては、Handlerでドメインオブジェクトを直接レスポンスとして返すことが推奨されない理由について教えていただいたことが印象的でした。これは、ドメインオブジェクトが変更された場合、レスポンスにも影響が出てしまう可能性があるためです。

### 6. VS CodeのTips

最後に、VS CodeのTipsを紹介します。今回のインターンでは、質問がある場合は、相談部屋というDiscordのチャンネルでメンターに質問し、画面共有をしてペアプログラミング形式でサポートしていただきました。（2時間半以上見ていただいた日も！本当にありがとうございます 😭）その中で、今まで知らなかった便利なVS Code操作を教えていただきました。（以下のコマンドは、Macでの操作になります。）

- **シンボルの名前変更**  
  F2  で、プロジェクト内の複数ファイルにまたがって、参照箇所で名前が一括で変更できます。これにより、複数ファイルを手動で変更する手間が省け、ミスも減ります 🌟  
  （今まで Command + D で複数選択して変更していましたが、複数ファイルを一括で変更できるということで感動しました！）

- **構造体の補完**  
  Command + . このショートカットは、VS Code の Go 拡張機能を使用しているときに、構造体の宣言部分で使用することで、構造体のフィールドを自動補完するために使われます。フィールドがまだ指定されていない構造体変数に対して、すべてのフィールドを埋めるための補完が提案されます。

これらのTipsを知ることで、VS Codeをさらに効率的に活用できるようになり、開発スピードが向上しました！みなさんもぜひ試してみてください。


## インターンを通じての感想

この5日間を通じて技術的な向上はもちろん、たくさんの学びがありました。メンターの皆さんは質問時に必ず公式ドキュメントを一緒に確認して教えてくださり、公式ドキュメントを調べる癖を身につけることができました。また、「褒めて伸ばす」がDMMの文化だそうで、わからないことだらけでしたが、質問中もたくさん褒めていただき、開発のモチベーションを維持して楽しむことができました。最終日はオフライン開催で、オフィス見学やライブコーディング、ディーエムエムビアバッシュに参加させていただいたりと、本当に充実した1週間でした。チームを組んでいただいたため、最終日はチームメイトがいるという安心感の中で楽しむことができました。
来年も開催予定とのことなので、皆さんぜひ応募をお勧めします。本当に素敵な会社様でした。1週間素敵な思い出を作ることができました、ありがとうございます😭🌟

追記：こちらの記事ですが、メンターの方々が見てくださり、アドバイスや温かいメッセージを沢山いただきました。また、インターン中に書いたコードも丁寧にレビューしていただき、こちらもたくさん褒めていただき、アドバイスもたくさんいただきました！インターン終了後も本当に手厚いサポートをありがとうございます。心より感謝申し上げます。（なんて素敵な会社で素敵な社員様方なんでしょうかー😭！！！本当にありがとうございました:pray:）