ginでシングルバイナリからファイルサーブすることを考えた。
用途を考えるとシングルバイナリ化する利点はあまりないこともあり、標準メソッドだけではできなかったので実装メモです。
以前に書いた記事も参考にした。
statikの使い方
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//パッケージのインストール //statikコマンドを使えるようになる go get github.com/rakyll/statik //assetフォルダをgoファイル化する statik asset ... import ( "github.com/rakyll/statik/fs" _ "projectname/statik" // TODO: Replace with the absolute import path ) ... |
http.FileSystem
として扱えるようになる。
ginのstaticFS
ファイルシステムの静的ファイルをサーブできるメソッド。
1 2 3 4 5 6 |
statikFS, err := fs.New() if err != nil { log.Fatal(err) } r:= gin.Default() r.StaticFS("/asset", statikFS) |
これが一番簡単だけどルートアクセスに設定できません。
static middleware(github)
ミドルウェアを使うことでルートに設定可能です。
1 |
r.Use(static.Serve("/", static.LocalFile("./assets", true))) |
これをstatikで使えるようにします。
Serve
の第2引数はServeFileSystem
なのでインターフェースを満たす必要がある。
1 2 3 4 |
type ServeFileSystem interface { http.FileSystem Exists(prefix string, path string) bool } |
Exists
メソッドが必要そうなのでミドルウェアの実装から必要なものを抜き出して実装してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
type statikFileSystem struct { fs http.FileSystem } func (b *statikFileSystem) Open(name string) (http.File, error) { return b.fs.Open(name) } func (b *statikFileSystem) Exists(prefix string, filepath string) bool { if _, err := b.fs.Open(filepath); err != nil { return false } return true } func StatikFileSystem(fs http.FileSystem) *statikFileSystem{ return &statikFileSystem{ fs, } } |
1 |
r.Use(static.Serve("/", StatikFileSystem(statikFS))) |
これでルートからでもファイルサーブできるようになった。