goi

package module
v1.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2024 License: BSD-3-Clause Imports: 30 Imported by: 0

README

goi

基于 net/http 进行开发的 Web 框架

goi 创建命令

使用 go env GOMODCACHE 获取 go 软件包路径:mypath\Go\pkg\mod + github.com\!never!stop!dreaming!wang\goi@v版本号\goi\goi.exe

使用 go env GOROOT 获取 go 安装路径 mypath\Go + bin 将可执行文件复制到 Go\bin 目录下

Windows: copy mypath\Go\pkg\mod\github.com\!never!stop!dreaming!wang\goi@v版本号\goi\goi.exe mypath\Go\bin\goi.exe

Linux: cp mypath\go\pkg\mod\github.com\!never!stop!dreaming!wang\goi@v版本号\goi\goi mypath\go\bin\goi

> goi

Usage(用法):                                         
        goi <command> [arguments]                      
The commands are(命令如下):                          
        create-project  myproject   创建项目       
        create-app      myapp       创建app

示例

# 创建项目
> goi create-project example

# 新建应用 app
> cd example
> goi create-app myapp

路由

多级路由

子父路由,内置路由转换器,自定义路由转换器

  • Router.Include(UrlPath) 创建一个子路由
  • Router.UrlPatterns(UrlPath, goi.AsView{GET: Test1}) 注册一个路由
静态路由

静态路由映射,返回文件对象即响应该文件内容

  • Router.StaticUrlPatterns(UrlPath, StaticUrlPath) 注册一个静态路由

中间件

  • 请求中间件:Server.MiddleWares.BeforeRequest(RequestMiddleWare) 注册请求中间件
  • 视图中间件:Server.MiddleWares.BeforeView(ViewMiddleWare) 注册视图中间件
  • 响应中间件:Server.MiddleWares.BeforeResponse(ResponseMiddleWare) 注册响应中间件

日志模块

  • 支持三种日志
    • 信息日志:Log.INFO_OUT_PATH
    • 访问日志:Log.ACCESS_OUT_PATH
    • 错误日志:Log.ERROR_OUT_PATH ERROR
  • 日志等级:是否开启 Log.DEBUG = true
    • DEBUG
      • 使用:goi.Debug()
      • 输出:Console(终端)、INFO 信息日志、ACCESS 访问日志、ERROR 错误日志
    • INFO
      • 使用:goi.Info()
      • 输出:Console(终端)、INFO 信息日志、ACCESS 访问日志
    • WARNING
      • 使用:goi.Warning()
      • 输出:Console(终端)、INFO 信息日志
    • ERROR
      • 使用:goi.Error()
      • 输出:Console(终端)、INFO 信息日志、ERROR 错误日志
    • MeteLog
      • 使用:goi.MetaLog()
      • 输出:Console(终端)、INFO 信息日志、ACCESS 访问日志、ERROR 错误日志
  • 日志切割:两种可同时设置满足任意一种即切割
    • 按照日志大小:Log.SplitSize
      • 例:Log.SplitSize = 1024 * 1024
    • 按照日期格式:Log.SplitTime = "2006-01-02"
      • 例:Log.SplitTime = "2006-01-02" 设置日期格式

ORM 模型

支持:MySQL、SQLite3

模型迁移
  • MySQL

    // MySQL
    type UserModel struct {
    	Id          *int64  `field:"int NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '用户id'" json:"id"`
    	Username    *string `field:"varchar(255) DEFAULT NULL COMMENT '用户名'" json:"username"`
    	Password    *string `field:"varchar(255) DEFAULT NULL COMMENT '密码'" json:"password"`
    	Create_time *string `field:"DATETIME DEFAULT NULL COMMENT '更新时间'" json:"create_time"`
    	Update_time *string `field:"DATETIME DEFAULT NULL COMMENT '创建时间'" json:"update_time"`
    }
    
    // 设置表配置
    func (UserModel) ModelSet() *model.MySQLSettings {
    	encryptFields := []string{
    		"username",
    		"password",
    	}
    
    	modelSettings := &model.MySQLSettings{
    		TABLE_NAME:      "user_tb",            // 设置表名
    		ENGINE:          "InnoDB",             // 设置存储引擎,默认: InnoDB
    		AUTO_INCREMENT:  2,                    // 设置自增长起始值
    		COMMENT:         "用户表",                // 设置表注释
    		DEFAULT_CHARSET: "utf8mb4",            // 设置默认字符集,如: utf8mb4
    		COLLATE:         "utf8mb4_0900_ai_ci", // 设置校对规则,如 utf8mb4_0900_ai_ci;
    		ROW_FORMAT:      "",                   // 设置行的存储格式,如 DYNAMIC, COMPACT, FULL.
    		DATA_DIRECTORY:  "",                   // 设置数据存储目录
    		INDEX_DIRECTORY: "",                   // 设置索引存储目录
    		STORAGE:         "",                   // 设置存储类型,如 DISK、MEMORY、CSV
    		CHECKSUM:        0,                    // 表格的校验和算法,如 1 开启校验和
    		DELAY_KEY_WRITE: 0,                    // 控制非唯一索引的写延迟,如 1
    		MAX_ROWS:        0,                    // 设置最大行数
    		MIN_ROWS:        0,                    // 设置最小行数
    		PARTITION_BY:    "",                   // 定义分区方式,如 RANGE、HASH、LIST
    
    		// 自定义配置
    		MySettings: model.MySettings{
    			"encrypt_fields": encryptFields,
    		},
    	}
    
    	return modelSettings
    }
    
  • SQLite

    // 用户表
    type UserSqliteModel struct {
    	Id          *int64  `field:"INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT" json:"id"`
    	Username    *string `field:"TEXT" json:"username"`
    	Password    *string `field:"TEXT" json:"password"`
    	Create_time *string `field:"TEXT NOT NULL" json:"create_time"`
    	Update_time *string `field:"TEXT" json:"update_time"`
    }
    
    // 设置表配置
    func (UserSqliteModel) ModelSet() *model.SQLite3Settings {
    	encryptFields := []string{
    		"username",
    		"password",
    	}
    
    	modelSettings := &model.SQLite3Settings{
    		TABLE_NAME: "user_tb", // 设置表名
    
    		// 自定义配置
    		MySettings: model.MySettings{
    			"encrypt_fields": encryptFields,
    		},
    	}
    	return modelSettings
    }
    
    
查询多条数据
func TestModelList(request *goi.Request) any {
	// mysqlObj, err := db.MySQLConnect("default", "mysql_slave_2")
	// defer mysqlObj.Close()
	SQLite3DB, err := db.SQLite3Connect("sqlite_1")
	defer SQLite3DB.Close()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	
	// mysql 数据库
	// var userSlice []UserModel
	// mysqlObj.SetModel(UserModel{}) // 设置操作表
	// err = mysqlObj.Fields("Id", "Username", "Password").Where("id>?", 1).Select(&userSlice)

	// sqlite3 数据库
	var userSlice []UserSqliteModel
	SQLite3DB.SetModel(UserSqliteModel{})
	err = SQLite3DB.Fields("Id", "Username", "Password").Where("id>? limit 1, 2", 1).Select(&userSlice)

	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	...
}
查询单条数据
func TestModelRetrieve(request *goi.Request) any {
	user_id := request.PathParams.Get("user_id").(int)
	
	if user_id == 0 {
		// 返回 goi.Response
		return goi.Response{
			Status: http.StatusNotFound, // Status 指定响应状态码
			Data:   nil,
		}
	}
	
	// mysqlObj, err := db.MySQLConnect("default", "mysql_slave_2")
	// defer mysqlObj.Close()
	SQLite3DB, err := db.SQLite3Connect("sqlite_1")
	defer SQLite3DB.Close()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	
	// mysql 数据库
	// user := UserModel{}
	// mysqlObj.SetModel(UserModel{}) // 设置操作表
	// err = mysqlObj.Fields("Id", "Username").Where("id=?", user_id).First(&user)

	// sqlite3 数据库
	user := UserSqliteModel{}
	SQLite3DB.SetModel(UserSqliteModel{})
	err = SQLite3DB.Fields("Id", "Username").Where("id=?", user_id).First(&user)

	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	...
}
新增一条数据
func TestModelCreate(request *goi.Request) any {
	// mysqlObj, err := db.MySQLConnect("default", "mysql_slave_2")
	// defer mysqlObj.Close()
	SQLite3DB, err := db.SQLite3Connect("sqlite_1")
	defer SQLite3DB.Close()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	username := request.BodyParams.Get("username").(string)
	password := request.BodyParams.Get("password").(string)
	create_time := time.Now().In(goi.Settings.LOCATION).Format("2006-01-02 15:04:05")
	// mysql 数据库
	// user := &UserModel{
	// 	Username:    &username,
	// 	Password:    &password,
	// 	Create_time: &create_time,
	// }
	// mysqlObj.SetModel(UserModel{})
	// result, err := mysqlObj.Insert(user)
	// result, err := mysqlObj.Fields("Id", "Password").Insert(user) // 指定插入字段
	
	// // sqlite3 数据库
	user := &UserSqliteModel{
		Username:    &username,
		Password:    &password,
		Create_time: &create_time,
	}
	SQLite3DB.SetModel(UserSqliteModel{})
	// result, err := SQLite3DB.Insert(user)
	result, err := SQLite3DB.Fields("Id", "Password", "Create_time").Insert(user)
	
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	id, err := result.LastInsertId()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	fmt.Println("id", id)
	
	user.Id = &id
	...
}
更新数据
func TestModelUpdate(request *goi.Request) any {
	user_id := request.PathParams.Get("user_id").(int)
	username := request.BodyParams.Get("username").(string)
	
	if user_id == 0 {
		// 返回 goi.Response
		return goi.Response{
			Status: http.StatusNotFound, // Status 指定响应状态码
			Data:   nil,
		}
	}
	
	// mysqlObj, err := db.MySQLConnect("default", "mysql_slave_2")
	// defer mysqlObj.Close()
	SQLite3DB, err := db.SQLite3Connect("sqlite_1")
	defer SQLite3DB.Close()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	update_time := time.Now().In(goi.Settings.LOCATION).Format("2006-01-02 15:04:05")
	// mysql 数据库
	// update_user := &UserModel{
	// 	Username:    &username,
	// 	Update_time: &update_time,
	// }
	// mysqlObj.SetModel(UserModel{})
	// result, err := mysqlObj.Where("id=?", user_id).Update(update_user)
	// result, err := mysqlObj.Fields("Username").Where("id=?", user_id).Update(update_user) // 更新指定字段
	
	// sqlite3 数据库
	update_user := &UserSqliteModel{
		Username:    &username,
		Update_time: &update_time,
	}
	SQLite3DB.SetModel(UserSqliteModel{})
	result, err := SQLite3DB.Where("id=?", user_id).Update(update_user)
	
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	rowNum, err := result.RowsAffected()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	if rowNum == 0 {
		return goi.Response{
			Status: http.StatusOK,
			Data: goi.Data{
				Status: http.StatusInternalServerError,
				Msg:    "修改失败!",
				Data:   nil,
			},
		}
	}
	fmt.Println("rowNum", rowNum)
    ...
}
删除数据
func TestModelDelete(request *goi.Request) any {
	user_id := request.PathParams.Get("user_id").(int)
	
	if user_id == 0 {
		// 返回 goi.Response
		return goi.Response{
			Status: http.StatusNotFound, // Status 指定响应状态码
			Data:   nil,
		}
	}
	
	// mysqlObj, err := db.MySQLConnect("default", "mysql_slave_2")
	// defer mysqlObj.Close()
	SQLite3DB, err := db.SQLite3Connect("sqlite_1")
	defer SQLite3DB.Close()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	// mysql 数据库
	// mysqlObj.SetModel(UserModel{})
	// result, err := mysqlObj.Where("id=?", user_id).Delete()
	
	// sqlite3 数据库
	SQLite3DB.SetModel(UserSqliteModel{})
	result, err := SQLite3DB.Where("id=?", user_id).Delete()
	
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	rowNum, err := result.RowsAffected()
	if err != nil {
		return goi.Response{
			Status: http.StatusInternalServerError,
			Data:   err.Error(),
		}
	}
	if rowNum == 0 {
		return goi.Response{
			Status: http.StatusOK,
			Data: goi.Data{
				Status: http.StatusOK,
				Msg:    "已删除!",
				Data:   nil,
			},
		}
	}
	fmt.Println("rowNum", rowNum)
	...
}

缓存

  • 支持过期策略,默认惰性删除
    • PERIODIC(定期删除:默认每隔 1s 就随机抽取一些设置了过期时间的 key,检查其是否过期)
    • SCHEDULED(定时删除:某个设置了过期时间的 key,到期后立即删除)
  • 支持内存淘汰策略
    • NOEVICTION(直接抛出错误)
    • ALLKEYS_RANDOM(随机删除-所有键)
    • ALLKEYS_LRU(删除最近最少使用-所有键)
    • ALLKEYS_LFU(删除最近最不频繁使用-所有键)
    • VOLATILE_RANDOM(随机删除-设置过期时间的键)
    • VOLATILE_LRU(删除最近最少使用-设置过期时间的键)
    • VOLATILE_LFU(删除最近最不频繁使用-设置过期时间的键)
    • VOLATILE_TTL(删除即将过期的键-设置过期时间的键)

内置 JWT Token

  • 生成 Token

    header := map[string]any{
        "alg": "SHA256",
        "typ": "JWT",
    }
    
    payloads := map[string]any{
        "user_id":  1,
        "username": "wjh123",
        "exp":      expTime,
    }
    token, err := jwt.NewJWT(header, payloads, "xxxxxx")
    
  • 验证 Token

    payloads, err := jwt.CkeckToken(token, "xxxxxx")
    if jwt.JwtDecodeError(err) { // token 解码错误!
       pass
    }else if jwt.JwtExpiredSignatureError(err) { // token 已过期
       pass
    }
    

详细示例:example

Documentation

Index

Constants

View Source
const (
	LFUInitValue    = 5   // LFU初始化值
	LFULogFactor    = 0.1 // LFU对数增长因子
	MaxCounterValue = 255 // 计数器最大值
)
View Source
const (
	DEBUG   logLevel = iota // 打印所有日志
	INFO                    // 打印所有日志
	WARNING                 // 打印 Warning、Error 日志
	ERROR                   // 打印 Error 日志
	MeteLog                 // 日志
)

日志等级

Variables

View Source
var Settings *metaSettings

Functions

func GenerateECCCertificate added in v1.0.13

func GenerateECCCertificate(certificateTemplate x509.Certificate, outPath string) error

func GenerateRSACertificate added in v1.0.13

func GenerateRSACertificate(certificateTemplate x509.Certificate, outPath string) error

func LFULogIncr

func LFULogIncr(counter uint8) uint8

计算 LFU 递增值

func RegisterConverter

func RegisterConverter(typeName string, converter string)

func Version

func Version() string

版本

Types

type AsView

type AsView struct {
	GET     HandlerFunc
	HEAD    HandlerFunc
	POST    HandlerFunc
	PUT     HandlerFunc
	PATCH   HandlerFunc
	DELETE  HandlerFunc
	CONNECT HandlerFunc
	OPTIONS HandlerFunc
	TRACE   HandlerFunc
	File    string   // 文件
	DIR     http.Dir // 文件夹
}

路由视图

type Data

type Data struct {
	Status int    `json:"status"`
	Msg    string `json:"msg"`
	Data   any    `json:"data"`
}

内置响应数据格式

type Engine

type Engine struct {
	Router      *metaRouter
	MiddleWares *metaMiddleWares
	Settings    *metaSettings
	Cache       *MetaCache
	Log         *MetaLogger
}

Engine 实现 ServeHTTP 接口

func NewHttpServer

func NewHttpServer() *Engine

创建一个 Http 服务

func (*Engine) HandlerHTTP

func (engine *Engine) HandlerHTTP(request *Request, response http.ResponseWriter) (result any)

处理 HTTP 请求

func (*Engine) Init added in v1.0.12

func (engine *Engine) Init()

初始化

func (*Engine) RunServer

func (engine *Engine) RunServer()

启动 http 服务

func (*Engine) ServeHTTP

func (engine *Engine) ServeHTTP(response http.ResponseWriter, request *http.Request)

实现 ServeHTTP 接口

type EvictPolicy

type EvictPolicy uint8 // 缓存淘汰策略
const (
	NOEVICTION      EvictPolicy = iota // 直接抛出错误,不淘汰任何已经存在的键
	ALLKEYS_RANDOM                     // 所有的键 随机移除 key
	ALLKEYS_LRU                        // 所有的键 移除最近最少使用的 key
	ALLKEYS_LFU                        // 所有的键 移除最近最不频繁使用的 key
	VOLATILE_RANDOM                    // 所有设置了过期时间的键 随机移除 key
	VOLATILE_LRU                       // 所有设置了过期时间的键 移除最近最少使用的 key
	VOLATILE_LFU                       // 所有设置了过期时间的键 移除最近最不频繁使用的 key
	VOLATILE_TTL                       // 所有设置了过期时间的键 移除快过期的 key
)

缓存淘汰策略

type ExpirationPolicy

type ExpirationPolicy uint8 // 过期策略
const (
	// 默认惰性删除:在获取某个 key 的时候,检查这个 key 如果设置了过期时间并且过期了,是的话就删除。
	// 定期删除:默认每隔 1s 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果有过期就删除。
	// 定时删除:某个设置了过期时间的 key,到期后立即删除。
	PERIODIC  ExpirationPolicy = iota // 定期删除
	SCHEDULED                         // 定时删除

)

过期策略

type Float

type Float interface {
	float32 | float64
}

type HandlerFunc

type HandlerFunc func(*Request) any

HandlerFunc 定义 goi 使用的请求处理程序

type Int

type Int interface {
	int | int8 | int16 | int32 | int64
}

type IntAll

type IntAll interface {
	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64
}

type MetaCache

type MetaCache struct {
	EVICT_POLICY      EvictPolicy      // 缓存淘汰策略
	EXPIRATION_POLICY ExpirationPolicy // 过期策略
	MAX_SIZE          int64
	// contains filtered or unexported fields
}
var Cache *MetaCache

func (*MetaCache) Del

func (cache *MetaCache) Del(key string)

Del 删除键值

func (*MetaCache) DelExp

func (cache *MetaCache) DelExp(key string) bool

DelExp 删除过期的 key, 如果 key 已过期则删除返回 true,未过期则不会删除返回 false

func (*MetaCache) Get

func (cache *MetaCache) Get(key string) (any, bool)

Get 查找键的值

func (*MetaCache) Set

func (cache *MetaCache) Set(key string, value any, expires int)

Set 设置键值

type MetaDataBase

type MetaDataBase struct {
	ENGINE       string
	NAME         string
	USER         string
	PASSWORD     string
	HOST         string
	PORT         uint16
	SERVICE_NAME string
}

数据库

type MetaLogger

type MetaLogger struct {
	DEBUG           bool   // 默认为 true
	INFO_OUT_PATH   string // 所有日志输出路径
	ACCESS_OUT_PATH string // 访问日志输出路径
	ERROR_OUT_PATH  string // 错误日志输出路径
	OUT_DATABASE    string // 所有日志输出到数据库
	SplitSize       int64  // 日志切割大小,默认为 1G 1024 * 1024 * 1024
	SplitTime       string // 日志切割大小,默认按天切割
	// contains filtered or unexported fields
}
var Log *MetaLogger

func NewLogger

func NewLogger() *MetaLogger

NewLogger 创建一个logger

func (*MetaLogger) Debug

func (logger *MetaLogger) Debug(log ...any)

日志方法 Debug 通用 Debug 日志

func (*MetaLogger) Error

func (logger *MetaLogger) Error(log ...any)

ERROR 通用 ERROR 日志

func (*MetaLogger) Info

func (logger *MetaLogger) Info(log ...any)

Info 通用 Info 日志

func (*MetaLogger) InitLogger

func (logger *MetaLogger) InitLogger()

日志初始化

func (*MetaLogger) MetaLog added in v1.0.12

func (logger *MetaLogger) MetaLog(log ...any)

Log 日志

func (*MetaLogger) Warning

func (logger *MetaLogger) Warning(log ...any)

WARNING 通用 WARNING 日志

type MetaSSL added in v1.0.13

type MetaSSL struct {
	STATUS    bool
	CERT_PATH string
	KEY_PATH  string
	CSR_PATH  string
}

SSL

type Request

type Request struct {
	Object      *http.Request
	Context     context.Context // 请求上下文
	PathParams  metaValues      // 路由参数
	QueryParams metaValues      // 查询字符串参数
	BodyParams  metaValues      // Body 传参
}

type RequestMiddleware

type RequestMiddleware func(*Request) any // 请求中间件

type Response

type Response struct {
	Status int
	Data   any
}

请求响应数据

type ResponseMiddleware

type ResponseMiddleware func(*Request, http.ResponseWriter) any // 响应中间件

type UInt

type UInt interface {
	uint | uint8 | uint16 | uint32 | uint64
}

type ViewMiddleware

type ViewMiddleware func(*Request, HandlerFunc) any // 视图中间件

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL