Golangの簡単な例
6572 ワード
1 main.go appを起動
2 app packetはdotwebフレームワークを用いてhttpサーバ、dotwebを構築する.New()が返すdotwebオブジェクトは、通常appと呼ばれ、ログ、キャッシュ、ホットロード、httpserverのロードなどの作業を担当します.コンテナ、宿主であり、httpserverはその環境で動作します.HttpServerは、リクエストの処理、ルーティング、セッション、ミドルウェアの管理などの機能を担当します.
サーバを初期化すると、ルーティング構成が初期化されます.
エラー処理モジュールの定義:
3 routerの実装ExtentControllerによるrouterの処理
4 ExtentControlの実装
5構成関連
およびプロファイル:
package main
import (
"log"
"github.com/track/blogserver/pkg/app"
)
func main() {
// app
app := app.NewApp()
defer app.Destory()
//
log.Fatal(app.Launch())
}
2 app packetはdotwebフレームワークを用いてhttpサーバ、dotwebを構築する.New()が返すdotwebオブジェクトは、通常appと呼ばれ、ログ、キャッシュ、ホットロード、httpserverのロードなどの作業を担当します.コンテナ、宿主であり、httpserverはその環境で動作します.HttpServerは、リクエストの処理、ルーティング、セッション、ミドルウェアの管理などの機能を担当します.
サーバを初期化すると、ルーティング構成が初期化されます.
package app
import (
"github.com/devfeel/dotweb"
"github.com/track/blogserver/pkg/config"
"github.com/track/blogserver/pkg/controllers"
"github.com/track/blogserver/pkg/routers"
)
//
type App struct {
Conf *config.BlogConfig
Server *dotweb.DotWeb
}
func NewApp() *App {
return &App{}
}
//
func (app *App) Launch() error {
app.Conf = config.Config()
app.initServer()
app.initRouter()
return app.Server.StartServer(app.Conf.ServerPort)
}
//
func (app *App) Destory() {
if app.Server != nil {
app.Server.Close()
}
}
//
func (app *App) initServer() {
app.Server = dotweb.New()
// Log
app.Server.SetEnabledLog(app.Conf.LogEnable)
app.Server.SetLogPath(app.Conf.LogPath)
// error
app.initError()
//
if app.Conf.EnvProd {
app.Server.SetProductionMode()
} else {
app.Server.SetDevelopmentMode()
}
// Gzip
app.Server.HttpServer.SetEnabledGzip(false)
}
//
func (app *App) initRouter() {
r := routers.NewApiRouter(app.Server.HttpServer)
// api/admin/xx api
r.Admin()
}
// error
func (app *App) initError() {
ec := controllers.NewErrorController()
app.Server.SetNotFoundHandle(ec.NotFound)
app.Server.SetExceptionHandle(ec.Internal)
app.Server.SetMethodNotAllowedHandle(ec.MethodNotAllowed)
}
エラー処理モジュールの定義:
package controllers
import (
"fmt"
"github.com/devfeel/dotweb"
"github.com/track/blogserver/pkg/common"
"net/http"
)
type ErrorController struct {
}
func NewErrorController() *ErrorController {
return &ErrorController{}
}
// 404
func (ec *ErrorController) NotFound(context dotweb.Context) {
context.WriteJsonC(http.StatusNotFound, common.ErrNotFound)
}
// 500
func (ec *ErrorController) Internal(context dotweb.Context, err error) {
errCust := common.Err{
Code: common.ErrInternal.Code,
Msg: fmt.Sprintf("%s %s", common.ErrInternal.Msg, err.Error()),
}
context.WriteJsonC(http.StatusInternalServerError, errCust)
}
// 405
func (ec *ErrorController) MethodNotAllowed(context dotweb.Context) {
context.WriteJsonC(http.StatusMethodNotAllowed, common.ErrMethodNotAllow)
}
3 routerの実装ExtentControllerによるrouterの処理
package routers
import (
"github.com/devfeel/dotweb"
"github.com/track/blogserver/pkg/controllers"
)
type Router struct {
server *dotweb.HttpServer
group dotweb.Group
}
//
func NewApiRouter(server *dotweb.HttpServer) *Router {
router := &Router{server: server, group: server.Group("/api")}
return router
}
func (r *Router) Admin() {
admin := r.group.Group("/admin")
//
addItem(admin.Group("/extends"))
}
func addItem(item dotweb.Group) {
ec := controllers.NewExtendController()
item.OPTIONS("", ec.Options)
item.POST("", ec.AddItem)
}
4 ExtentControlの実装
package controllers
import (
"bufio"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/devfeel/dotweb"
"github.com/track/blogserver/pkg/common"
"github.com/track/blogserver/pkg/models"
"github.com/track/blogserver/pkg/services"
"github.com/track/blogserver/pkg/utils"
)
type ExtendController struct {
}
func NewExtendController() *ExtendController {
return &ExtendController{}
}
func (ec *ExtendController) Options(ctx dotweb.Context) error {
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") //
ctx.Response().SetHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
ctx.Response().SetHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With,Sign")
return ctx.WriteJsonC(http.StatusNoContent, nil)
}
func (ec *ExtendController) AddItem(ctx dotweb.Context) error {
//
orderno := ctx.FormValue("orderno")
uid := ctx.FormValue("uid")
origin := ctx.FormValue("itemid")
originnum := ctx.FormValue("itemnum")
// ,
v := utils.Validation{}
if v.Required(orderno) || v.Required(uid) || v.Required(origin) || v.Required(originnum) {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrClientParams, Data: nil})
}
//
WriteItemFile(orderno, uid, origin, originnum)
//
return ctx.WriteJsonC(http.StatusOK, models.Response{Err: common.Err{Msg: common.MsgResistSucc}, Data: nil})
}
5構成関連
package config
import (
"fmt"
"os"
"path/filepath"
"sync"
"github.com/BurntSushi/toml"
)
// server config
// use: config.Config() return *BlogConfig single instance
var (
cfg *BlogConfig
sOnce sync.Once
lock = &sync.RWMutex{}
)
//
type BlogConfig struct {
LogEnable bool `toml:"log_enable"`
LogPath string `toml:"log_path"`
ServerPort int `toml:"server_port"`
EnvProd bool `toml:"environment_prod"`
}
//return single config instance
func Config() *BlogConfig {
sOnce.Do(decodeConfig)
lock.RLock()
defer lock.RUnlock()
return cfg
}
//decode config with toml file
func decodeConfig() {
path := os.Getenv("APP_CONFIG_PATH")
if len(path) <= 0 {
path = "./config/config_debug.toml"
}
fp, err := filepath.Abs(path)
if err != nil {
panic(fmt.Errorf(" Read Config Path Err: %s", fp))
}
config := new(BlogConfig)
if _, err := toml.DecodeFile(fp, config); err != nil {
panic(fmt.Errorf("DecodeFile Config Err: %s", err.Error()))
}
lock.Lock()
cfg = config
lock.Unlock()
}
およびプロファイル:
# This block as Server Config
log_enable = true #
log_path = "/var/log/blogserver" #
server_port = 8888 #
environment_prod = false # , true