LoginSignup
6
6

More than 5 years have passed since last update.

Go + Vue + MySQLの基盤を晒す

Posted at

はじめに

社会人として働き始めて技術と知識もついてきたので、初心に返ってTODOアプリを作成しようと思いました。
言語やフレームワークは気分で選びました。

方針としてはdocker-compose build, docker-compose upの2コマンドだけで完結できるように作成しました。
実際まだ半分くらいしか出来ていないのでフロントとか全くかけていないです。(むしろ @Angelan1720に手伝ってもらっています)

作成中のリポジトリ
以下の記事を参考にしながら作成して、ハマったところや気づいたところなどを書いていきます。

 参考にした記事

構成

.
├── README.md
├── docker/
│   ├── client/
│   ├── golang/
│   └── mysql/
└── docker-compose.yml
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の時に全部入れてくれるのはいいですよね。
golang/Dockerfile

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しまくってました。(いい案があるなら教えて欲しいです)

ハマった点はgormstringで渡された日時を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を定義する際、CreatedAtUpdatedAtを上のように定義すると自動的にCreatedAtUpdatedAtを入れてくれます。

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

client/Dockerfile

FROM node:10.12-alpine as build-stage
WORKDIR /app
COPY . .
RUN yarn install
CMD yarn serve

クライアント側は現時点ではほとんど作成していないのでVueが立ち上がってくれればいいかな程度まで作成しました。
Vueはそんなに詳しくないでのとりあえずaxiosvue-routerを使って色々試してみます。

これからやっていきたいこと

  1. とりあえず完成させて公開したい
  2. REST-APIで作成したのでswaggerを使ってAPIドキュメントも作りたい
  3. ユーザ登録をfirebaseを使用してGoogleアカウントでログインできるようにしたい
6
6
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
6
6