20200221のGoに関する記事は3件です。

VScodeでGo開発環境のセットアップ(Ubuntu18.04)

環境

バージョン: 1.41.1
コミット: 26076a4de974ead31f97692a0d32f90d735645c0
日付: 2019-12-18T15:04:31.999Z
Electron: 6.1.5
Chrome: 76.0.3809.146
Node.js: 12.4.0
V8: 7.6.303.31-electron.0
OS: Linux x64 4.15.0-76-generic

拡張機能のインストール

Extensions から Goインストール
Ctrl+Shift+Pでコマンドパレットを開いて、GO: Install/Update toolsを実行
全ツールを選択してインストール

サンプルコード

package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world.")
    i := 101
    fmt.Println(i)
}

はまったこと

デバッグ実行したらなんか怒られた。

version of go is too old for this version of delve (minimum supported version 1.11, suppress this error with --check-go-version=false)

色々調べると、aptでgolangをインストールすると1.10が入るっぽく、
delveは1.11以上を要求するのでデバッグできないみたい。

https://golang.org/doc/install?download=go1.13.7.linux-amd64.tar.gz
ここを参考に手動で1.11以上のVersionを入れてPATHを通す。

tar -C /usr/local -xzf go1.13.7.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

うごいたー!!

1.jpg

おわり。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golangのデータベース操作を雑多にまとめる

本当に雑多に走り書き、DBはsqlite3を用いる。

テーブルの作成

func main() {
    DbConnection,  _ := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()
    cmd := `CREATE TABLE IF NOT EXISTS person(
                name STRING,
                age INT)`
    _, err := DbConnection.Exec(cmd)
    if err != nil {
        log.Fatalln(err)
    }
}

テーブルに挿入

func main() {
    DbConnection := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()
    cmd := "INSERT INTO person (name age) VALUES (?, ?)"
    _, err := DbConnection.Exec(cmd, "Nancy", 24)
    if err != nil {
        log.Fatalln(err)
    }
}

テーブルを更新

func main() {
    DbConnection := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()
    cmd := "UPDATE person SET age = ? WHERE user_id = ?"
    _, err := DbConnection.Exec(cmd, "1234)
    if err != nil {
        log.Fatalln(err)
    }
}

テーブルからMultiple Selectし、結果をPerson構造体のスライスに詰める

DbConnection.Queryを使い、結果をrows.Next()でループを回す

type Person struct {
    Name string
    Age int
}

func main() {
    DbConnection := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()

    cmd := "SELECT * FROM person WHERE"
    rows, _ := DbConnection.Query(cmd)

    var persons []Person
    for rows.Next() {
        var p Person
        err := rows.Scan(&p.Name, &p.Age)
        if err != nil {
            log.Println(err)
        }
        persons = append(persons, p)
    }
}

テーブルからSingle Selectし、結果をPerson構造体にする

DbConnection.QueryRowを使う。

func main() {
    DbConnection := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()

    cmd := "SELECT * FROM person WHERE age = ?"
    row := DbConnection.QueryRow(cmd, 28)

    var Person p
    err := row.Scan(&p.Name, &p.Age)

    if err != nil {
        // 条件を満たすものが見つからない場合
        if err == sql.ErrNoRows {
            log.Println("No row")
        // そういうわけではないがエラー
        log.Println(err)
    }
}

テーブルからデータを削除

func main() {
    DbConnection := sql.Open("sqlite3", "./data.sql")
    defer DbConnection.Close()

    cmd := "DELETE FROM person WHERE user_id = ?"
    row := DbConnection.Exec(cmd, 1234)

    if err != nil {
        log.Fatalln(err)
    }
}

クエリインジェクション対策

  • valueは?でエスケープする
  • ただし、table名は?で挿入できず、%sをplaceholderとする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

個人的GoとVueの繋げ方(CORS,FileServer)

今回はVueとGolangをつなげる際に死にかけたところを書くよ

作成時

結構前に短縮URLのバックエンドを作成してホッとしていました。
が、今度はフロントエンドの作成というわけですよ

初めてフロントエンドに挑戦ということでVue.jsを使ってましたが...

まぁ、初めて触ったらなんのこっちゃで分からんがな ←なにやってんだ

直接Vueのページに見ても何書いてるか分からない
なんとなく1画面をサンプル見ながら作ってみてた
VueだとSPAとかが作れるって?
ページたくさん作らずにできるなら便利そうだな...
って思いながらrouterで接続先を設定とかカチカチ...

とりあえず手探りでやって、どうにかフロントエンドのWeb画面はできました。
Golangとは違って1.5ヶ月かかりましたね...

さて問題がここからだ

GolangとVueをつなごうかと思って
まずはaxiosを見つけて導入してみました。
axiosでGetメソッドやPostメソッドを作って
データの取得や新規作成などができるし、非常にわかりやすいので採用!!
エンドポイントを指定して、受け取り方を設定して動かすぜ!!

て、思ってたんですよ...CORSに出会うまでは

localhostで動かそうとするとね、バックエンドとフロントエンドが噛み合わないんですよ
どうやらWebブラウザでは、Webサイトが持つ情報が別の悪意あるサイトに使われないためにSame-Origin Policyというものがあるのです。
悪意あるサイトに使われないために制限をかけているのは良いのですが、信頼しているものまで制限をかけやがるのですよ
別に私は悪意なんてないんですがね...

そこで出会ったのはCORSですよ

CORSって?

CORSはあるWebサイトから別のWebサイトへのアクセスを許可するものです
これを作らないとGolangとVue.jsの間に橋がかからないのです

Golang(go-chi使ってます)では

main.go
func main() {

    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(middleware.RealIP)
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)
    r.Use(middleware.Timeout(60 * time.Second))
    r.Use(Cors)
}
func Cors(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := appengine.NewContext(r)
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        w.Header().Set("ExposedHeaders", "Link")
        w.Header().Set("Access-Control-Allow-Credentials", "true")
        log.Infof(ctx, "Should set headers")
        if r.Method == "OPTIONS" {
            log.Infof(ctx, "Should return for OPTIONS")
            return
        }
        next.ServeHTTP(w, r)
    })
}

を書き足してあげればいけるはず
MethodやHeaderは自分で調整ということで

Vue.jsではconfigで調整しましょう

index.html
proxy: {

      './': {
        target: 'http://localhost:8080',
        ws: true,
        changeOrigin: true
      }
     },

これでlocalhostでつなぎました。

よっしゃ繋いだぜ、ひゃっほいで終わったら良かったのですが、
ここからが本当の地獄の始まりでした

Golangでlocalhost立ち上げると真っ白です

繋ぐことがわかったのでVue側で色んなモジュール見つけては便利にしようと色々試して「ええやん...これ」と思ってました。
vue-good-tableを使ってみたり、bootstrap-bueでデザインの良いボタンつけてみたりしてみたんですよ

いざそれでGolangで開くとですね...真っ白...
幻影でも見てたかのように真っ白でした。
エラーを見るとcss,jsなどなど読み取れねーよと

これを解決する方法はhttp.FileServer,http.StripPrefixが鍵となりました
これはVueで作った静的なページを返すというものです。
これを使ってjs,css,vue-good-tableなどを読んであげます
でもこれだけだと宣言しただけなのでこれを使ってあげます
http.StripPrefixで指定したパスをhttp.FileServerが捜索するURLを取り除きましょう

main.go
var vueTemplate *template.Template

func main() {
    r.Get("/", VueHandler)
    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(middleware.RealIP)
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)
    r.Use(middleware.Timeout(60 * time.Second))
    r.Use(Cors)

    //Vue.jsで作成したの静的ページを返す
    //これを使用しないとGolangでVueのパッケージなどが表示されない
    static := http.FileServer(http.Dir("./(your-file-name)/dist/static"))
    table := http.FileServer(http.Dir("./(your-file-name)/node_modules/vue-good-table"))
    css := http.FileServer(http.Dir("./(your-file-name)/dist/static/css"))
    js := http.FileServer(http.Dir("./(your-file-name)/dist/static/js"))
    public := http.FileServer(http.Dir("./(your-file-name)/public"))
    src := http.FileServer(http.Dir("./(your-file-name)/src"))

    //http.StripPrefix()は、第1引数に指定したパスを、http.FileServer()が捜索するURLから取り除く。
    http.Handle("/static/", http.StripPrefix("/static/", static))
    http.Handle("/vue-good-table/", http.StripPrefix("/vue-good-table/", table))
    http.Handle("/css/", http.StripPrefix("/css/", css))
    http.Handle("/js/", http.StripPrefix("/js/", js))
    http.Handle("/public/", http.StripPrefix("/public/", public))
    http.Handle("/src/", http.StripPrefix("/src/", src))
    http.Handle("/", r)
    appengine.Main()
}

//Vue.jsのindex.htmlを読み込み ブラウザで表示する処理
func VueHandler(w http.ResponseWriter, r *http.Request) {
    vueTemplate = template.Must(template.ParseFiles("./(your-file-name)/dist/index.html"))
    err := vueTemplate.ExecuteTemplate(w, "index.html", siteKey)
    if err != nil {
        log.Errorf(appengine.NewContext(r), err.Error())
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    return
}

以上です

これに気づかずにずっと沼ってしまった私ですが、どうにか脱出できました。
参考程度に書きましたが、大丈夫かな?
ではでは(^^)

参考URL

http://www.tohoho-web.com/ex/same-origin-policy.html Some-Origin-Policy
https://qiita.com/mochizukikotaro/items/6b72ad595db8a6b5514f GOやPHPのCORSがより詳しいです
https://www.kabanoki.net/3230/ Vue-Good-Tableの参考です
https://blog.y-yuki.net/entry/2017/05/19/163000 http.StripPrefixの参考です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む