JSONによるAPIサーバーをGoで実装し、それをフロントエンドから利用することでフロント側を任意のフロントエンドフレームワークで実装することは可能です。
nodeの開発サーバーとGoによるバックエンド開発を並行する場合、僕は以下の構成で開発しています。
- nodeの開発サーバーをlocalhost:3000にて起動
- golangの下記サーバー実装をlocalhost:8080にて(開発版ビルド)起動
- localhost:8080/api/へのアクセスはGoがハンドリングします。
- 開発版ビルドの場合、/api/を除くスタティックコンテンツへのアクセスはlocalhost:3000にプロキシーします。
- リリースビルドの場合、スタティックコンテンツがバイナリに埋め込まれてビルドされ、スタティックコンテンツをサーブします。
つまり、リリースビルドの直前にnode側でpublicフォルダに静的ファイル群のデプロイをすましておきます。
開発中
ミニマムなサンプルとして下記のツリーと仮定します。
- 開発版ビルド: go run . # node開発サーバー(localhost:3000)も必要
- リリースビルド: go run -tags release . # next.jsのデプロイstaticファイルセットがfront/publicにある前提
- project-root/
- go.mod
- main.go
- debug.go
- release.go
- api/
- api.go
- front/public/
- index.html
https://play.golang.org/p/27Gs-a5dh-P
go
1package main
2
3import (
4 "log"
5 "net"
6 "net/http"
7
8 _ "play.ground/api"
9)
10
11func main() {
12 l, err := net.Listen("tcp", ":8080")
13 if err != nil {
14 log.Fatal(err)
15 }
16 log.Print("listen:", l.Addr())
17 if err := http.Serve(l, nil); err != nil {
18 log.Fatal(err)
19 }
20}
21
22-- go.mod --
23module play.ground
24
25-- api/api.go --
26package api
27
28import "net/http"
29
30var API = http.NewServeMux()
31
32func health(w http.ResponseWriter, r *http.Request) {
33 // implement sample api
34}
35
36func init() {
37 API.HandleFunc("/api/health", health)
38}
39
40
41-- development.go --
42// +build !release
43
44package main
45
46import (
47 "log"
48 "net/http"
49 "net/http/httputil"
50 "net/url"
51)
52
53func init() {
54 u, err := url.Parse("http://localhost:3000/")
55 if err != nil {
56 log.Fatal(err)
57 }
58 http.Handle("/", httputil.NewSingleHostReverseProxy(u))
59}
60
61-- release.go --
62// +build release
63
64package main
65
66import (
67 "embed"
68 "io/fs"
69 "log"
70 "net/http"
71)
72
73//go:embed front/public/*
74var content embed.FS
75
76func init() {
77 pub, err := fs.Sub(content, "front/public")
78 if err != nil {
79 log.Fatal(err)
80 }
81 http.Handle("/", http.FileServer(http.FS(pub)))
82}
83
84-- front/public/index.html --
85<h1>Hello!</h1>