QUREOにおけるマスターデータの取扱とGo言語での実装について

こんちには。QUREOサーバーサイドエンジニアの辻です。
QUREOではAPIサーバーをGo言語で実装しています。
今回はQUREOにおけるGo言語の使用例を1つ紹介させていただきたいと思います。

QUREOとは

「QUREO」(キュレオ)は、小学生のためのプログラミングスクール Tech Kids Schoolと、サイバーエージェントグループのゲーム会社、株式会社アプリボットが共同開発した、オンラインで学べる新しいプログラミング学習サービスです。
カリキュラムは、「Tech Kids School」が監修。
プログラミング未経験のお子様でも楽しく、自立的に学習を進めることができます。
全300以上のレッスン(学習期間:約2~3年)を通じて、本格的なプログラミングの基礎となる技術力を身につけることが可能です。よろしければぜひ使ってみて下さい。

マスターデータの取扱

QUREOではプログラミングコースやチャレンジコースといったゲーム要素があり、これらは全てマスターデータから成り立っています。
(マスターデータの定義は人によって様々かもしれませんが、ここではマスターデータ=処理の基本となるデータとします)

マスタデータ管理方法ですが、QUREOではスプレッドシートを使用して管理していて、
スプレッドシート → sqlファイル生成 → 生成されたsqlファイルをgit管理 → Jenkinsで各環境へ反映
といった流れで開発環境や本番環境にマスターデータ反映を行います。

Jenkinsではバージョン指定でデータ反映出来るように設定してあります。
こうすることでエンジニア以外もデータ反映が可能になります。

  • バージョン指定で各環境へ反映

起動時にマスターデータを全て読み込む

マスターデータを取得するために、都度データベースにアクセスしていては負荷がかかってしまいます。
それを回避するために起動時にマスターデータを全て読み込むようにします。

  • イメージ図

一例としてm_eventテーブルの情報を起動時に取得して読み込む実装をしてみます。
※実際にQUREOで使用しているコードとは異なります

  • 起動時にデータを読み込み、構造体に格納
mEvent.go
type MEvent struct {
    mEventDtoAll []MEventDto
}

// 起動時に読み込む
func NewMEvent(db *sql.DB) *MEvent {
    m, err := getMEventDto(db) // DBからデータ取得
    if err != nil {
        log.Fatal(err)
    }

    // DBから取得したデータを構造体に格納
    return &MEvent{
        mEventDtoAll: m,
    }
}

func (m *MEvent) GetAll() []MEventDto {
    return m.mEventDtoAll
}

func getMEventDto(db *sql.DB) ([]MEventDto, error) {
    rows, err := db.Query("SELECT id,name FROM m_event")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    var result []MEventDto
    for rows.Next() {
        var id int
        var name string

        if err := rows.Scan(&id, &name); err != nil {
            log.Fatal(err)
        }

        result = append(result, MEventDto{
            ID:   id,
            Name: name,
        })
    }

    return result, nil
}

// MEventDto
type MEventDto struct {
    ID   int
    Name string
}
  • GetAllメソッドを使用することによってマスターデータ取得の際にsqlを発行しなくてもよい。
service.go
type MEventService struct {
    mEvent *dao.MEvent
}

func NewMEventService(db *sql.DB) *MEventService {
    mEvent := dao.NewMEvent(db)

    return &MEventService{
        mEvent: mEvent,
    }
}

func (s *MEventService) GetMEventAll() []dao.MEventDto {
    return s.mEvent.GetAll()
}

起動時に実行されるNewMEvent関数の中でデータベースから取得した情報を構造体に格納します。
m_eventテーブルの情報を取得したい場合は、GetAllメソッドを使用すればデータベースにアクセスすることなくm_eventテーブルの情報を取得可能です。
このような実装にすることでデータベースにアクセスする頻度が減り、負荷が軽減されます。
QUREOではマスターデータ取得に関して、上記のような方法をとっています。

まとめ

今回はGo言語での使用例を紹介させて頂きました。
今後もGo言語の便利な使い方やノウハウが貯まれば紹介していきたいと思います!