LoginSignup
2
4

More than 1 year has passed since last update.

Docker環境を構築し、Golang Echo v5-alphaでJWT Token認証 ホットリロード、リモートデバッグ、マイグレーション、GormのORMが入ったフルスタックフレームワークチックな環境の構築をした

Last updated at Posted at 2022-06-16

docker環境を構築し、
Go言語のフレームワークのechoフレームワークに、
JWT Token認証 ホットリロード、リモートデバッグ、マイグレーション、
GormのORMと色々入ったフルスタックフレームワークチックな環境の構築をしてみました。

今回の記事は、この記事の作成の為に公開しました、gihubのソースの動かし方の説明になります。
※githubのソースは記事の一番下になります。

記事の評判がよければ、ライブラリーの比較や説明、ソースコードの説明等記事を更新するかもしれません。

※ validation、テストは入っておりません。
あと、errorハンドリングやlog出力等できていないです。

この記事は、golang初心者やechoフレームワークをこれから学ぶ人向けとなります。
自分は、golangの学習を初めて時間があまり経っていないので、少し説明やソースコードに粗がありますが、ご容赦ください

あと、元々echo v4で作っていたのを、echo v5-alphaに書き換えているので、
v5-alphaの作法に書き変わっていない部分があります。

今回詰まった点は下記の記事に載せております。


Golangを始めた理由は、phpに飽きてきたのと
LaravelやRailsといった動的型付け言語のフルスタックフレームワークは、
すこぶる実行速度が遅いという理由です。

laravelでいうとEloquentが機能の中で一番遅い為、build queryやPDOといった物で代用したりするケースもありますが、
個人的にそこまでするのであれば、そもそも使わない方が良いのではと思います。
そもそも便利なModelや認証自体自作しないといけなくなり苦行です。
また、そこまでしてもベースが遅いのでそこまでする意味がありません

あと、動的型付け言語はDDDといった設計との相性も良くないといわれており
設計をこだわるなら初めからScalaといった言語を選定すれば良いと思ってしまいます。


echoフレームワーク選定理由なのですが、
Go言語のフレームワーク中で軽量かつ一番高速に動く為です。

小規模〜中規模までのシステムや
マイクロサービス化のbackendに使用するならechoが良さそうです。

他のフレームワークもかなり悩んだのですが、やはり、高速で動くという点に
心動かされました。


何故、この記事とgithubのリポジトリーを公開したのか?
なのですが、自分も含め、ehcoをインストールすると下記のキャプチャーのように
2ファイル、go.mod、go.sumしかインストールされず、初学者には実装イメージも掴めずハードルが高いと思ったからです。

あと、Laravelみたいに、マイグレーションやEloquentみたいにSQLを書かなくてもDB操作ができたりし
少しでも、簡単に開発できるようにしたかったからです。
あと、echoは、Apiサーバー用に使われすのが普通なので、JWT token必須なので導入しました。

ちなみgo.mod、go.sumの説明なのですが、
phpのcomposerでいうと、go.modがcomposer.json、go.sumがcomposer.lockにあたり、
nodeでいうと、go.modがpackage.json、go.sumがyarn.lockやpackage-lock.jsonになります。

余談になりますが、Go言語のパッケージ管理なのですが、
色々短期間に変更されているみたいで、
現在は、Go Modulesが一般的です。

モジュールのインストール方法は、go getだったのですが、
Go1.18 からは、go installに完全に切り替わります。

goのDockerfileもgo getからgo installに書き換えております。

go get

RUN go get github.com/pilu/fresh

go install

RUN go install github.com/pilu/fresh@latest

違いは、go getはバージョンを指定できなかったのに対し、
go installはバージョンを指定する必要があります。

go install github.com/ライブラリー@バージョン

となります。

※ 下記はecho v4 インストール直後のフォルダ構成
スクリーンショット 2022-06-16 1.44.20.png

ではどういう風に学習していったかというと
echoで既に組まれたサンプルを落とし、自分で肉付けしてイメージをつけていきました。
参考にさせて頂きました記事はこちらになります。
オニオンアーキテクチャーかクリーンアキテクチャーで迷ったのですが、
設計に詳しくないですが、あまり変わらないということなので、
オニオンアーキテクチャーを選択しました。

こちらは、goのライブラリー管理が「Gopkg.toml」と「Gopkg.lock」で古かったり
一部のライブラリーの開発が終了していたりしていた為、
再度ライブラリー選定し入れ直したりしております。


利用ライブラリー

go-sql-driver

golang-jwt

golang-migrate

jinzhu/gorm

上記を使っていますが、
下記が公式のgormになります。恐らく下記を使った方が良いかもしれません。
※ jinzhu/gormは、公式gormをforkして作られています。

※ go-gorm/gorm

spf13/viper


公開リポジトリーの動かし方

一番最後のリポジトリをgit cloneした後、docker-compose.ymlのtargetを任意のものに
変更してください、target prodとdevはコメントアウトしている為、
そのままdockerを立ち上げるとホットリロード + リモートデバッグ環境になります。
必ずどれかひとつのみ設定してください。

docker-compose.yml

services:
  back:
    build:
      context: .
      dockerfile: app/Dockerfile #Dockerfileの場所
      # target: prod    # 本番用
      # target: dev     # 開発用(ホットリロード)
      target: dev-debug # 開発用(ホットリロード + リモートデバッグ)
    volumes:

上記を編集後、

docker-compose up -d

を行いdockerを立ち上げてください。

※ docker ps で起動中コンテナ確認
docker exec -i -t echo-backend-v5-alpha_back_1 sh

でechoの置いてあるコンテナに移動し、

その後、dbフォルダに移動し

cd /go/src/app/db

下記のコマンドでマイグレーションの実行を行なってください、
テーブルが自動で生成されます。

go run migrate.go -exec up

マイグレーションなのですが、下記の方の記事の方法を参考に動かない部分は直しほぼそのまま使っております。

※ /go/src/appにgo.sumが生成されていなければ、
下記を実施しgo moduleをインストールしてください
恐らくdockerを立ち上げると生成されていると思います。

go mod tidy

もしくは

go get

デバッグ設定

Goland

下記の用に、Debug Configurationsの設定をこなってください

スクリーンショット 2022-06-17 0.22.28.png

Visual Studio Code

下記を参考に拡張機能をインストール後、リポジトリーをcloneしたら
.vscode/launch.jsonを用意していますので、こちらを読み込んでください。

スクリーンショット 2022-06-17 0.26.34.png


起動確認

上記手順まで行い下記の、URLにアクセスすると
起動しません。

スクリーンショット 2022-06-17 0.33.43.png

docker-compose.yml の下記のtargetをdev-debugで立ち上げると
そのままアクセスしても、うまく動きません、
target: devや、target: prodで立ち上げるとそのまま開きます。

こちらは、マルチステージングビルドになり、
Dockerfileのどのコンテナを使うか指定しています。

マルチステジーングビルドとは、
デプロイするなら、軽量なOSでビルドされた物だけを、
開発で使うのであれば、リモートデバッグやリアルタイムでコンパイルできるホットリロード環境が入った物など
用途によってどのコンテナを使うか選ぶことができます。
マルチステジーングビルドを使わないと環境ごとに、Dockerfileを用意しないといけないので、
大変便利です。

services:
  back:
    build:
      context: .
      dockerfile: app/Dockerfile #Dockerfileの場所
      # target: prod    # 本番用
      # target: dev     # 開発用(ホットリロード)
      target: dev-debug # 開発用(ホットリロード + リモートデバッグ)
    volumes:

で、ホットリロード + リモートデバッグで立ち上げた場合は、
必ず、エディター上で一度、デバックしてください、
スクリーンショット 2022-06-17 0.49.54.png
で、立ち上げたら、ステップ実行やり切るか、リモートデバッグを中断してください、
Golandの場合は、下記のように、Yesを押して中断すると、Debugできなくなるので
注意してください、Visual Studio Codeは大丈夫です。
スクリーンショット 2022-06-17 0.50.18.png

で、下記のように、画面が表示されたら起動確認完了です。
スクリーンショット 2022-06-17 0.50.53.png

デバッグできなくなったら、コンテナに入り、

docker exec -i -t echo-backend-v5-alpha_back_1 sh

/go/src/app パスで、

air -c ./air.toml

を実行してください。
スクリーンショット 2022-06-17 1.01.19.png
その後、再度、上記の手順通りに、デバッグ開始してください

しかし、何故、ホットローデイングとホットリロード + リモートデバッグの環境を分けているかというと、

ホットリロード + リモートデバッグは、go-delve + air
というライブラリーを使っており、この環境では、開発中にエラーが発生すると
コンパイルエラーが発生し完全にサーバー自体が止まってしまい為です。

ホットリロードは、freshというライブラリーを使っており、
こちらでは、コンパイルエラーが発生したとしても止まらず動いてくれる為
残しております。
go-delveとfreshを組み合わせて環境構築しようとしましたが、
うまくいかず断念しております。

fresh

go-delve + airの設定は下記を参考にさせて頂きました。


動作確認

サインアップ

  curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"name":"Golang man", "email":"test@gmail.com", "password":"test5555"}' \
  localhost:5566/api/signup

レスポンス

  {"id":1,"name":"Golang man","email":"test@gmail.com","password":"$2a$10$/Yt3rqgEDNXf3Ot/Wf8qfempj/GJcGgv.f4cjioNvJXDR7kPgO2CS","created_at":"2022-06-15T15:30:03.1773644Z","updated_at":"2022-06-15T15:30:03.1773644Z"}

ログイン

curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"email":"test@gmail.com", "password":"test5555"}' \
localhost:5566/api/login

レスポンス

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiYWRtaW4iOnRydWUsImV4cCI6MTY1NTU2NjgyNn0.c1x7Eml70EkuvTT1DcfLlr9ECC7OuTUcQNDdbU74ot4"}

token認証確認

curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiYWRtaW4iOnRydWUsImV4cCI6MTY1NTU2NjgyNn0.c1x7Eml70EkuvTT1DcfLlr9ECC7OuTUcQNDdbU74ot4" localhost:5566/api/auth/refresh

レスポンス

{"id":1,"name":"Golang man","email":"test@gmail.com","password":"$2a$10$/Yt3rqgEDNXf3Ot/Wf8qfempj/GJcGgv.f4cjioNvJXDR7kPgO2CS","created_at":"2022-06-16T00:30:03+09:00","updated_at":"2022-06-16T00:30:03+09:00"}

こちらリポジトリーになります。

反応が良ければこちらの記事やリポジトリー内容を更新しようと思いますので
記事が参考になりましたら、LGTMお願いします。

あと、別記事で、echoとNext.js(redux、redux-toolkit、react-hook)、ISR(incremental static regeneration)や
また、Nuxt.jsの3系が出たら、ISR(incremental static regeneration)も使えるので
backendとフロントを組み合わせたサンプル載せようと思っております。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4