Angular+Golang(gin)でSPAを作る


目標

Angularで作成したSPA(シングルページアプリケーション)に対して、GolangのWebフレームワークであるginを使ってHTTPアクセスできるようにします。

なぜginを使うか。

  • ログがわかりやすいから。
  • 記事が見当たらなかったから

前提

  • 「Angularのチュートリアル」を通していること。

  • チュートリアル程度のAngular CLIが使えること。

  • 既に、ご自身で作成されたAngularプロジェクトがあることを想定しています。

ご自身で作成されたAngularプロジェクトがない場合:
後述する「プロジェクトをコピー」の手順を無視して進めてください。
デフォルトで生成されるSPAを表示することができます。

手順

プロジェクト作成

始めのプロジェクト構成は以下のようにしています。

go-angular
└── main.go


go-angularディレクトリに移動して、Angularプロジェクトを作成します。

UHNaKZ:go-angular $ ng new view
? Would you like to add Angular routing? Yes      // Yesを入力
? Which stylesheet format would you like to use? CSS // CSSを選択


プロジェクトの構成が以下のようになります。

go-angular
├── main.go
└── view
    ├── README.md
    ├── angular.json
    ├── e2e
    ├── karma.conf.js
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── src
    ├── tsconfig.app.json
    ├── tsconfig.json
    ├── tsconfig.spec.json
    └── tslint.json

プロジェクトをコピー

注意! 上記の「プロジェクト作成」で生成したプロジェクト以外に、ご自身で作成されたAngularプロジェクトがない場合は無視してください

ここで、生成されたviewディレクトリ配下のsrcディレクトリを、既に作成済みのプロジェクトのsrcディレクトリに置き換えます。

Angularプロジェクトをビルド

viewディレクトリへ移動してビルドします。

UHNaKZ:go-angular $ cd ./view
UHNaKZ:go-angular/view $ ng build

すると、

go-angular
├── main.go
└── view
    ├── README.md
    ├── angular.json
    ├── dist       // NEW!!
    ├── e2e
    ├── karma.conf.js
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── src
    ├── tsconfig.app.json
    ├── tsconfig.json
    ├── tsconfig.spec.json
    └── tslint.json

のようになったかと思います。

Goビルド

go-angular/main.goを以下のように修正します。

go-angular/main.go

package main
import(
    "github.com/gin-gonic/gin"
)
func main(){
    router := gin.Default()
    router.Static("/", "./view/dist/view")
    router.Run()
}



修正できたらビルドします。

UHNaKZ:go-angular $ go build

最後に、生成されたバイナリファイルを実行します。

UHNaKZ:go-angular $ ./go-angular

localhost:8080にアクセスすれば、Angularで作ったSPAが動いているのが分かると思います。

ginを使わずに標準パッケージだけで書いたコード

main.go
package main
import (
    "net/http"
)
func main(){
    ang := http.FileServer(http.Dir("./view/dist/view"))
    http.Handle("/",ang)
    http.ListenAndServe(":8080",nil)
}

ログが出ないです。
ログが出るようにすると少し長くなる。

main.go
import (
    "net/http"
    "fmt"
    "time"
)
func main(){
    http.HandleFunc("/",angSF)
    fmt.Println(" Your Angular application is runnning.")
    http.ListenAndServe(":8080",nil)
}
func angSF(w http.ResponseWriter, r *http.Request){
    t := time.Now().Format("Mon Jan 2 15:04:05 -0700 MST 2006")
    fmt.Println(fmt.Sprintf("%s  Status:%v Method:%s URL:%s",t,http.StatusOK,r.Method,r.URL))
    http.ServeFile(w,r,"./view/dist/view")
}

ログこんな感じで作れば良いんかな。(ステータスは面倒なので200しか返さないです。)

まとめ

ginが楽。