序言
上章 Go-Spring 入門篇(五) 講到對上傳服務的抽象,完成了 controler
對 service
的解耦。
本章我們實現一個物件儲存和本地檔案儲存能力的更換,通過 go-spring
提供的 Condition 來限制 Bean 的註冊以及動態設定配置項。
Minio
使用 minio 作為遠端物件儲存服務。
docker-compose
這裡我們通過 docker
快速的建立一個本地 minio
服務。
version: "3"
services:
minio:
image: bitnami/minio:latest
ports:
- "9000:9000"
- "9001:9001"
environment:
- MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE
- MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
- BITNAMI_DEBUG=true
config/application.properties
新增 minio
配置。
# minio
minio.enable=true
minio.host=127.0.0.1
minio.port=9000
minio.access=AKIAIOSFODNN7EXAMPLE
minio.secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
minio.secure = false
minio.bucket=gs-demo
modules/minio/minio.go
註冊 minio
啟動器。
package minio
import (
"context"
"fmt"
"github.com/go-spring/spring-base/log"
"github.com/go-spring/spring-core/gs"
"github.com/go-spring/spring-core/gs/cond"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
type MinioConfig struct {
Enable bool `value:"${minio.enable:=true}"` // 是否啟用 HTTP
Host string `value:"${minio.host:=127.0.0.1}"` // HTTP host
Port int `value:"${minio.port:=9000}"` // HTTP 埠
Access string `value:"${minio.access:=}"` // Access
Secret string `value:"${minio.secret:=}"` // Secret
Secure bool `value:"${minio.secure:=true}"` // Secure
Bucket string `value:"${minio.bucket:=}"`
}
func init() {
gs.Provide(clientMinio).
// Bean 名稱
Name("minio-client").
// cond.OnProperty 會檢查配置項
On(cond.OnProperty("minio.enable", cond.HavingValue("true")))
}
func clientMinio(config MinioConfig) *minio.Client {
// 建立 minio 物件
client, err := minio.New(fmt.Sprintf("%s:%d", config.Host, config.Port), &minio.Options{
Creds: credentials.NewStaticV4(config.Access, config.Secret, ""),
Secure: config.Secure,
})
if err != nil {
panic("minio client error" + err.Error())
}
// 建立儲存桶
err = client.MakeBucket(context.Background(), config.Bucket, minio.MakeBucketOptions{
// 嘻嘻,這個桶是外太空的
Region: "waitaikong",
ObjectLocking: false,
})
if err != nil {
panic(fmt.Sprintf("make %s bucket error: %v", config.Bucket, err))
}
log.Infof("%v", client.EndpointURL())
return client
}
記得收集匯入到 main.go
services/services.go
本地儲存 service
需要在沒有註冊 minio-client
的情況才註冊。
package services
import (
"github.com/minio/minio-go/v7"
"learn/services/filesystem/local"
fminio "learn/services/filesystem/minio"
"learn/types"
"github.com/go-spring/spring-core/gs"
"github.com/go-spring/spring-core/gs/cond"
)
func init() {
gs.Object(new(local.Service)).
Export((*types.FileProvider)(nil)).
// 本地儲存,當 minio 不存在時才註冊
// 可以新增其它判斷條件,例如 aliyun 等
On(cond.Group(cond.And, cond.OnMissingBean((*minio.Client)(nil))))
gs.Object(new(fminio.Service)).
Export((*types.FileProvider)(nil)).
// 當 minio-client 物件存在時
On(cond.OnBean((*minio.Client)(nil)))
}
services/filesystem/minio/minio.go
package minio
import (
// ...
"github.com/minio/minio-go/v7"
)
type Service struct {
// 自動注入 minio-client
Client *minio.Client `autowire:""`
// 儲存桶
Bucket string `value:"${minio.bucket}"`
// 儲存路徑
Dir string `value:"${file.dir}"`
}
func (s *Service) PutObject(name string, r io.Reader, size int64) (string, error) {
// ...
}
func (s *Service) ExistsObject(name string) bool {
// ...
}
然後啟動 docker-compose up -d minio
啟動 minio
服務。
重新執行 go run main.go
並測試,功能正常。
$ curl -F "file=@./1.jpg" http://127.0.0.1:8080/upload
$ {"code":0,"data":{"url":"temp/1.jpg"},"msg":"上傳檔案成功"}
$ curl -F "file=@./1.jpg" http://127.0.0.1:8080/upload
$ {"code":-1,"msg":"檔案已存在,請勿重複上傳"}
上傳後,通過 127.0.0.1:9001 在瀏覽器開啟 minio 的管理介面,可以發現檔案已經上傳成功。
修改 config/application.properties
的 minio.enable
可以切換儲存能力。
到此我們的入門篇就結束了。
謝謝大家,嘻嘻!
官網及交流
本作品採用《CC 協議》,轉載必須註明作者和本文連結