Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GolangとMySQLを接続して、APIを作ってみた

 GolangとMySQLを接続して、APIを作ってみた

DOG #2 で登壇した際のスライドです。
Golangは初心者の域を超えていませんが、使ってみて課題等が浮き彫りになってきた事を話してみました。

k_yoshikawa

June 26, 2019
Tweet

More Decks by k_yoshikawa

Other Decks in Programming

Transcript

  1. GolangとMySQLを接続して、 APIを作ってみた 2019/6/26 @DOG #2 k_yoshikawa

  2. 自己紹介 名前:吉川和樹(k_yoshikawa) 所属:株式会社デザインワン・ジャパン アカウント: twitter: @hunhunyosshy qiita: @k_yoshikawa スキル: エンジニア歴4年弱(=PHPer)

    Goは多分15時間くらい
  3. 注意事項 • 本内容は所属組織としての発表ではありません • Go素人がなんとか奮闘した物語です • 参考レベルに留めていただけると嬉しいです • 行数の関係上、説明に不要なコードはスライドには書いていません •

    ですので、このままではエラーが起こるものが多数あります • 詳細は、 GitHub をご覧ください
  4. 目次 1. 前提の話をしてみた! 2. SQLドライバーを使ってMySQLを接続してみた! 3. 環境変数設定ライブラリを使って環境変数を設定してみた! 4. 共通で使う処理を別ファイルにまとめてみようとした! 5.

    ディレクトリ構成について少しだけ考えてみた! 6. MySQLから取ってきたRowデータを構造体に格納してみた! 7. WebAPIとしてjson形式で取得してみた! 8. まとめてみた!
  5. もっといい感じに話せる内容を考えていた 1.前提の話をしてみた!

  6. 構成はこんな感じで妄想 バックエンド:Golang(Docker上で動かしたいなあ) DB: MySQL(どうしよっかなーAWSのサービス使っちゃおうかな) フロントエンド:Vue.js(Docker上で動かしたいなあ) その他:AWS上で動かしたいなあ 1.前提の話をしてみた!

  7. ただ家庭/技術的な課題が多数あり・・・ 1.前提の話をしてみた!

  8. 発表に間に合わないので予定変更 バックエンド:Golang(Docker とりあえずローカル ) DB: MySQL(AWSのサービス とりあえずローカル) フロントエンド:Vue.js(Docker上で動かしたいなあ) その他:AWS上で動かしたいなあ APIを作ることに注力する!!

    1. 前提の話をしてみた!
  9. 扱うデータはこれだけ(MySQLの意味・・・) 1. 前提の話をしてみた!

  10. GolangとMySQLを接続して、 APIを作ってみた 2019/6/26 @DOG #2 k_yoshikawa

  11. go-sql-driver/mysql https://github.com/go-sql-driver/mysql これを使って、mysqlを接続してみる! 2. SQLドライバーを使ってMySQLを接続してみた!

  12. main.go import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) func main() {

    db, err := sql.Open("mysql", "root:[email protected]/shogi") ・・・ rows, err := db.Query("SELECT * FROM opening") 2. SQLドライバーを使ってMySQLを接続してみた!
  13. 接続できたけどパスワード丸出し・・・ 3.環境変数設定ライブラリを使って環境変数を設定してみた!

  14. joho/godotenv https://github.com/joho/godotenv これを使って環境変数を設定する! 3.環境変数設定ライブラリを使って環境変数を設定してみた!

  15. .env DB_NAME=***** DB_ROLE=***** DB_PASSWORD=********** 3.環境変数設定ライブラリを使って環境変数を設定してみた!!

  16. func main() { err := godotenv.Load() if err != nil

    { panic(err.Error()) } db, err := sql.Open("mysql", os.Getenv("DB_ROLE") + ":" + os.Getenv("DB_PASSWORD") + "@/" + os.Getenv("DB_NAME") ・・・ rows, err := db.Query("SELECT * FROM opening") 3.環境変数設定ライブラリを使って環境変数を設定してみた!
  17. この接続処理毎回書くの?やだなあ 4.共通で使う処理を別ファイルにまとめてみようとした!

  18. func Connect() *sql.DB { err := godotenv.Load() ・・・ db, err

    := sql.Open("mysql", os.Getenv("DB_ROLE")+":"+os.Getenv("DB_PASSWORD")+"@/"+os.Get env("DB_NAME")) ・・・ return db } 4.共通で使う処理を別ファイルにまとめてみようとした!
  19. あとはこれをimportすれば何とかなるはず! 4.共通で使う処理を別ファイルにまとめてみようとした!

  20. あれ、ちょっと待てよ・・・ どこにどう置くといいのかなあ そういや「スタンダードがあるよ」て教えてもらったなあ ちょっと調べてみるか 5. ディレクトリ構成について少しだけ考えてみた!

  21. golang-standards/project-layout https://github.com/golang-standards/project-layout そうそう、これこれ!こんなのあったわ! 5. ディレクトリ構成について少しだけ考えてみた!

  22. golang-standards/project-layout その中の記述には・・・ /pkg Library code that's ok to use by

    external applications (e.g., /pkg/mypubliclib). Other projects will import these libraries expecting them to work, so think twice before you put something here :-) 共通化できるファイルはpkg/配下に置けばいい(と判断) 5. ディレクトリ構成について少しだけ考えてみた!
  23. golang-standards/project-layout 5. ディレクトリ構成について少しだけ考えてみた!

  24. connect.go (これでsql接続処理はOKのはず!) import ( "database/sql" "os" _ "github.com/go-sql-driver/mysql" "github.com/joho/godotenv" )

    func Connect() *sql.DB { ・・・ 5. ディレクトリ構成について少しだけ考えてみた!
  25. openingdao.go (こんな感じでデータ取得を書く) import ( "github.com/hunhunyosshy/black-and-white/pkg/db" ) func FetchIndex() []Opening {

    db := db.Connect() ・・・ 5. ディレクトリ構成について少しだけ考えてみた!
  26. あれ、ちょっと待てよ・・・ どこにどう置くといいのかなあ そういや「スタンダードがあるよ」て教えてもらったなあ ちょっと調べてみるか 6. MySQLから取ってきたRowデータを構造体に格納してみた!

  27. 取得したデータはどう扱えばいいだろう・・・ 6. MySQLから取ってきたRowデータを構造体に格納してみた! 取ってきたときは、ただのRowsのデータ これだと扱いにくいなあ・・・ Goオブジェクトに似た「構造体」という概念があったなあ 構造体に格納してみるか!

  28. openingdao.go //構造体を用意 type Opening struct { ID int `json:"id"` Name

    string `json:"name"` } 6. MySQLから取ってきたRowデータを構造体に格納してみた!
  29. openingdao.go (こんな感じでデータを格納!) func FetchIndex() []Opening { db := db.Connect() rows,

    err := db.Query("SELECT * FROM opening”) openingArgs := make([]Opening, 0) for rows.Next() { var opening Opening err = rows.Scan(&opening.ID, &opening.Name) openingArgs = append(openingArgs, opening) } return openingArgs 6. MySQLから取ってきたRowデータを構造体に格納してみた!
  30. gorilla/mux でルーティングしてみることに https://github.com/gorilla/mux 7. WebAPIとしてjson形式で取得してみた!

  31. main.go func main() { r := mux.NewRouter() r.HandleFunc("/opening/", showOpeningIndex) log.Fatal(http.ListenAndServe(":8080",

    r)) } func showOpeningIndex(w http.ResponseWriter, r *http.Request) { w.Write([]byte(jsonEncode(openingdao.FetchIndex()))) } 7. WebAPIとしてjson形式で取得してみた!
  32. できた! 7. WebAPIとしてjson形式で取得してみた!

  33. まとめ • チュートリアルを進めるのと、自分で考えて作るのでは全然違った ◦ 「やりたい」ことができなくてもどかしい • 他言語でできるものは、大抵Goでも何とかなりそう • 「他言語ならできるのに」のギャップを埋めるのは勉強になりそう •

    実際に作ってみて、弱いところが浮き彫りになってきた ◦ 自分の場合ポインタ周りが弱いので、そのあたりはしっかり復習する • 実際に作るのは楽しいのでおすすめ!! 8.まとめてみた!
  34. ご静聴ありがとうございました! 8.まとめてみた!

  35. 参考URL 前述したライブラリ群のGitHub • https://github.com/go-sql-driver/mysql • https://github.com/joho/godotenv • https://github.com/golang-standards/project-layout • https://github.com/gorilla/mux

    その他参考にしたリンク • https://qiita.com/taizo/items/54f5f49c6102f86194b8 • https://qiita.com/sueken/items/87093e5941bfbc09bea8