Next.js と Go で WebSocket 通信を行おう【環境構築編】

# はじめに
今回は Next.js と Go を使った WebSocket 通信のやり方を2回に分けて紹介していきたいと思います。

1. [Next.js と Go で WebSocket 通信を行おう【環境構築編】](https://qiita.com/1129-tame/items/39101ed81039542198dc) <- 今回の記事
1. [Next.js と Go で WebSocket 通信を行おう【接続編】](https://qiita.com/1129-tame/items/2036d89915b3a3d026be)

私は現在個人開発でWebSocketによる双方向通信を利用したサービスを開発しています。
Next.js で立てたサーバーと Go で立てたサーバーを WebSocket で接続する記事があまりなく、結構苦労したので備忘録代わりにまとめたいと思い、この記事を書きました。

まずは環境構築編です。第1回目のこの記事ではモノレポでサーバーを立ち上げて Next.jsの default 画面と Go のサーバーで `Hello, World!` が出力される所まで行いたいと思います。

今回のコードは github で公開しています。 
環境構築終了時点のコードは `initial` ブランチに保存しています。

https://github.com/1129-tame/next-go-websocket/tree/initial

# 対象読者
- Next.js, Go を触っている初心者
※当方は Go に関してはあまり詳しくはないので文法など詳細については触れません。

# 環境構築
1. Docker 環境構築
1. Next.js, Go でサーバー構築

上記の手順で行います。
## Docker 環境構築
VSCode の Dev Container を利用して Docker 環境を構築して node.js と Go を使用できる状態にします。

### Dev Containerとは？
Dev Container についての詳細な説明は下記記事によくまとまっているのでそれを参考にしてください。
手軽にサクッと環境構築できるのでおすすめです。
Windows, Mac 等 OS 問わず利用できるはずです。

https://jpdscore.github.io/blog/vscode/devcontainer_intro/

https://weseek.co.jp/tech/2331/

### node.js, Goがインストールされたコンテナを作成 
それでは早速 Dev Container を使って node.js と Go が使えるコンテナを作成していきます。拡張機能がインストールされている前提で話を進めます。
1. command + shift + p を押し、`:remote-containers.createDevContainerFile`を開きます。
※MacのコマンドなのでWindowsは少し違いますが調べれば出てくると思います。
2. select 画面が表示されるので node.js と Go を選択し、ファイルを作成します。
   - devcontainer.json と Dockerfile という2つのファイルが作成されるはずです。
2. Reopen containerを選択し Dev Container を起動します。

## バージョン確認
VSCode 内のターミナルで以下の様なコマンドを入力して期待する出力がされればOKです。
※バージョンが一致しない可能性はありますのでその点はご留意ください。
```bash
$ node -v
v16.15.1
$ go version
go version go1.18.3 linux/arm64
```
# Next.js, Go でサーバー構築
次にフロント, バックそれぞれの環境構築や設定を行いたいと思います。
## Next.jsでサーバー構築
ますは Next.js の設定から。
今回は TypeScript も使用するので利用できる様にします。TypeScriptはフロントエンド開発において必須になってきているのでたとえ個人開発でも使用することを薦めます。

### Next.js, TypeScriptの導入
Next,js はコマンド1つでサクッとやってくれます。
```bash
$ yarn create next-app front  --typescript
```
上記コマンドを入力すると`front`ディレクトリが作成され、 TypeScript の設定も行ってくれます。 Next.js はゼロコンフィグを掲げているだけあって便利ですね。

### その他設定(お好みで)
#### file移動
pagesとstylesをsrc配下に入れます。好みなのでやるのかはおまかせです。
```bash
$ mkdir src
$ mv pages src/pages
$ mv styles src/styles
```
#### eslint や prettier の設定
formatの設定は最初にやっておくと後々便利ですが、マストではないので設定したい方は下記記事等参考にしてください。

https://zenn.dev/rabbit/articles/d7175e62dc56a5

### 起動確認
```bash
$ cd front
$ yarn dev
```
https://localhost:3000 にアクセスして以下の画面が出ていればNext.jsの環境構築ができています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180763/94b49728-4966-1812-4c33-259472b51930.png)

## Go でサーバー構築
続いてはサーバーサイド開発に用いる Go を使ってサーバーを構築していきたいと思います。
1. backend ディレクトリを作成し、必要なモジュールを入れます。今回は Go のフレームワークである echo を利用します。
    ```bash
    $ mkdir backend
    $ cd backend
    $ go mod init <リポジトリパス>
    $ go get github.com/labstack/echo/v4
    $ go get github.com/labstack/echo/v4/middleware
    ```

2. `server.go` ファイルを backend ディレクトリ配下に作成し、以下の様に書き込みます。

    ```bash
    $ touch serve.go
    ```

    ```go:serve.go
    package main

    import (
	    "net/http"

	    "github.com/labstack/echo/v4"
	    "github.com/labstack/echo/v4/middleware"
    )

    func main() {
	    e := echo.New() // インスタンスを作成
	    e.Use(middleware.Logger()) // ミドルウェアを設定

	    e.GET("/", func(c echo.Context) error { // ルートを設定
		    return c.String(http.StatusOK, "Hello, World!") // 出力
	    })

	    e.Logger.Fatal(e.Start(":8080"))　// サーバーをポート番号8080で起動
    }
    ```
1. サーバーを立ち上げるために以下コマンドを入力
    ```bash
    $ go run serve.go
    ```
1. http://localhost:8080 にアクセス
Hello, World! が表示されるのでサーバーの立ち上げが出来ました。

# おわりに
これで `localhost:3000` で Next.js のサーバーが。
`localhost:8080` で Go のサーバーが起動できました。

次回はこの2つの異なるポート番号を持つサーバー同士を WebSocket で通信できるようにしたいと思います。

https://qiita.com/1129-tame/items/2036d89915b3a3d026be

続編の記事が公開されたのでぜひご覧ください。

# 参考文献

https://jpdscore.github.io/blog/vscode/devcontainer_intro/

https://weseek.co.jp/tech/2331/

https://zenn.dev/rabbit/articles/d7175e62dc56a5

https://zenn.dev/empenguin/articles/bcf95c19451020

https://zenn.dev/def_yuisato/articles/echo-get-started

# 公式

https://nextjs.org/learn/foundations/about-nextjs?utm_source=next-site&utm_medium=homepage-cta&utm_campaign=next-website

https://go.dev/learn/

https://echo.labstack.com/guide/