はじめに
社会人として働き始めて技術と知識もついてきたので、初心に返ってTODOアプリを作成しようと思いました。
言語やフレームワークは気分で選びました。
方針としてはdocker-compose build
, docker-compose up
の2コマンドだけで完結できるように作成しました。
実際まだ半分くらいしか出来ていないのでフロントとか全くかけていないです。(むしろ @Angelan1720に手伝ってもらっています)
作成中のリポジトリ
以下の記事を参考にしながら作成して、ハマったところや気づいたところなどを書いていきます。
参考にした記事
- 今日から始めるDocker【docker-composeを使ってGo & Mysqlをよしなに起動しよう編】
- 「Vue.js + Go言語 + Firebase 」で始める! Frontend & Backend API 両方で認証するセキュアなSPA開発ハンズオン!
構成
.
├── README.md
├── docker/
│ ├── client/
│ ├── golang/
│ └── mysql/
└── docker-compose.yml
version: '3'
services:
mysql:
container_name: todo-mysql
image: mysql:5.7
ports:
- "3306:3306"
environment:
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: todo-mysql
volumes:
- ./db-data:/var/lib/mysql
- ./docker/mysql/my.cnf:/etc/mysql/my.cnf
- ./docker/mysql/init/:/docker-entrypoint-initdb.d
golang:
links:
- mysql
build: ./docker/golang/
ports:
- "8090:8080"
volumes:
- ./docker/golang/:/go/src/
command: sh ./scripts/start_app.sh
vue:
build: ./docker/client
ports:
- 8888:8080
volumes:
- ./docker/client:/app
- /app/node_modules
volumes:
db-data:
driver: local
MySQL
Dockerfile
は特に用意せずに公式のイメージからとってきました。 特別なことはしていません。
気づいた点
docker-compose up
の際DBを作成してmysql/init
配下にあるsqlを実行するのですが、ファイルの名前順に実行されるのでテーブルを作成する前にテストデータをinsertしてしまうことがあったのでファイル名の先頭に数字をつけました。
└── init
├── 1.todo.sql
├── 2.users.sql
└── testdata.sql
Go
- フレームワークはginを使用。特に選定理由はないです。
- ORMはgormを使用。日本語のドキュメントも割と充実しているのでとてもいいです。
- 依存関係は
modules
を使用。 buildの時に全部入れてくれるのはいいですよね。
FROM golang:latest
RUN apt-get update -qq && \
apt-get install -y mysql-client vim
WORKDIR /go/src/
COPY . .
ENV GO111MODULE=on
RUN go build
RUN go install
ENV PATH /go/bin:$PATH
私はvscode
で開発を行っていたので自分のローカルにパッケージがないと補完してくれないのでgo get
しまくってました。(いい案があるなら教えて欲しいです)
ハマった点はgorm
でstring
で渡された日時をinsertする際、時間がズレてしまうことが起こってしまいました。原因としてMySQLのタイムゾーンを疑いましたが、Go側のタイムゾーンの問題でした。
limitDate := "2018-03-31 12:00:00"
timeformat := "2006-01-02 15:04:05"
loc, _ := time.LoadLocation("Asia/Tokyo")
t, err := time.ParseInLocation(timeformat, limitDate, loc)
if err != nil {
panic(err)
}
ParseInLocation
を使用して、タイムゾーンに合わせたtime型に変換することで解決しました。
gormのいいところ
TODOをDBに登録する際、おそらく作成日(created_at)と更新日(updated_at)のカラムは必要となると思います。
type Todo struct {
ID int `json:"id"`
UserID int `json:"user_id"`
Context string `json:"context"`
LimitDate *time.Time `json:"limit_date"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
TODO
のstructを定義する際、CreatedAt
とUpdatedAt
を上のように定義すると自動的にCreatedAt
とUpdatedAt
を入れてくれます。
todo := Todo{}
todo.UserID = userID
todo.Context = context
todo.LimitDate = &t
db.Create(&todo) // CreatedAtとUpdatedAtを入れてくれる
todo := Todo{}
todo.ID = ID
todo.UserID = userID
db.Model(&todo).Updates(Todo{Context: context, LimitDate: &t}) // UpdatedAtを更新してくれる
Vue
FROM node:10.12-alpine as build-stage
WORKDIR /app
COPY . .
RUN yarn install
CMD yarn serve
クライアント側は現時点ではほとんど作成していないのでVueが立ち上がってくれればいいかな程度まで作成しました。
Vueはそんなに詳しくないでのとりあえずaxios
とvue-router
を使って色々試してみます。
これからやっていきたいこと
- とりあえず完成させて公開したい
- REST-APIで作成したので
swagger
を使ってAPIドキュメントも作りたい - ユーザ登録を
firebase
を使用してGoogleアカウントでログインできるようにしたい