方是golang web框架

yjp 26dab800a2 合并 2 天之前
convenient e600106aae 修改bug 1 月之前
framework 26dab800a2 合并 2 天之前
test fe290d3a17 添加缓存接口 2 天之前
.gitignore 28edc4f6d8 创建文件 6 月之前
LICENSE 29b2054764 Initial commit 6 月之前
README.md 73014e0228 修改README 4 月之前
baize.go 255e7aad72 修改Bug 4 月之前
go.mod 6f77bdd7fd 修改IDs转化错误 2 月之前
go.sum 6f77bdd7fd 修改IDs转化错误 2 月之前

README.md

Web框架——白泽

image

1. 概述

白泽,中国古代神话中的瑞兽。能言语,通万物之情,知鬼神之事,“王者有德”才出现,能辟除人间一切邪气。

该Web框架取名为白泽,希望框架能够通开发者之情,辟除一些Bug。

白泽基于六边形架构并结合方是科技的技术栈进行设计。主要包含framework包和convenient包,framework包是白泽框架的基础包,包含核心框架,网关框架和API Binding机制,大家可以基于该包的接口进行开发, convenient包则是在framework包基础上的封装,提供了更加便捷的接口用于构造Web后端应用。

2. Quick Start

下面的代码给出了白泽框架的的简单使用,使用白泽,一般直接利用binding进行开发即可,封装了最底层的AddRoute方式,一般仅在需要动态引出API时,才使用AddRoute方式。

package main

import (
	"fmt"
	"git.sxidc.com/go-framework/baize"
	"git.sxidc.com/go-framework/baize/framework/binding"
	"git.sxidc.com/go-framework/baize/framework/core/api"
	"git.sxidc.com/go-framework/baize/framework/core/api/request"
	"git.sxidc.com/go-framework/baize/framework/core/api/response"
	"git.sxidc.com/go-framework/baize/framework/core/application"
	"git.sxidc.com/go-framework/baize/framework/core/domain"
	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
	DEATH "github.com/vrecan/death"
	"net/http"
	"syscall"
)

func main() {
	app := baize.NewApplication(application.Config{
		ApiConfig: application.ApiConfig{
			UrlPrefix: "service",
			Port:      "10100",
		},
	})

	app.Api().
		RootRouter().
		AddMiddlewares(func(c *api.Context) {
			fmt.Println("Global Before1")
			c.Next()
			fmt.Println("Global After1")
		}, func(c *api.Context) {
			fmt.Println("Global Before2")
			c.Next()
			fmt.Println("Global After2")
		}).
		AddRoute(http.MethodGet, "/route", func(c *api.Context) {
			fmt.Println("By Add Route")
		})

	rootBinder := binding.NewBinder(app.ChooseRouter(api.RouterRoot, ""), app.Infrastructure())

	binding.GetBind(rootBinder, &binding.SimpleBindItem[any]{
		Path:             "/ping",
		SendResponseFunc: response.NoResponse,
		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
			c.String(http.StatusOK, "pong")
			return nil, nil
		},
	}, func(c *api.Context, i *infrastructure.Infrastructure) {
		fmt.Println("Root Route Before1")
		c.Next()
		fmt.Println("Root Route After1")
	}, func(c *api.Context, i *infrastructure.Infrastructure) {
		fmt.Println("Root Route Before2")
		c.Next()
		fmt.Println("Root Route After2")
	})

	app.Api().
		PrefixRouter().
		RegisterVersionedRouter("v1", func(c *api.Context) {
			fmt.Println("Global Before1")
			c.Next()
			fmt.Println("Global After1")
		}, func(c *api.Context) {
			fmt.Println("Global Before2")
			c.Next()
			fmt.Println("Global After2")
		}).
		AddRoute(http.MethodGet, "/route", func(c *api.Context) {
			fmt.Println("By Add Route")
		})

	prefixRootBinder := binding.NewBinder(app.ChooseRouter(api.RouterPrefix, "v1"), app.Infrastructure())

	binding.GetBind(prefixRootBinder, &binding.SimpleBindItem[any]{
		Path:             "/ping",
		SendResponseFunc: response.NoResponse,
		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
			c.String(http.StatusOK, "pong")
			return nil, nil
		},
	}, func(c *api.Context, i *infrastructure.Infrastructure) {
		fmt.Println("Versioned Route Before1")
		c.Next()
		fmt.Println("Versioned Route After1")
	}, func(c *api.Context, i *infrastructure.Infrastructure) {
		fmt.Println("Versioned Route Before2")
		c.Next()
		fmt.Println("Versioned Route After2")
	})

	go func() {
		if err := app.Start(); err != nil {
			panic(err)
		}
	}()

	defer func() {
		if err := app.Finish(); err != nil {
			panic(err)
		}
	}()

	death := DEATH.NewDeath(syscall.SIGINT, syscall.SIGTERM)
	_ = death.WaitForDeath()
}

3. application

白泽框架整体遵循六边形架构,如下图所示:

image

整体围绕Application展开,Application以Domain作为核心并协调API和基础设施构建业务逻辑。可以通过application.App的接口获取到响应的基础设施和API对象,可以使用基础设施或构建API。

4. api

api包含了定义API需要用到的相关接口和结构,request包含了请求参数和请求参数绑定的相关函数,response包含了常用的响应结构和响应函数.

Api结构内包含了Router接口,这里Router接口有两种子类型:RootRouter和PrefixRouter。RootRouter是最基础的根路由,指向的路径是http://ip:port,PrefixRouter是添加前缀的路由,指向的路径是http://ip:port/prefix,基于两种路由都可以进一步定义版本限制的路由,如http://ip:port/v1http://ip:port/prefix/v1。可以通过Api结构对路由进行定义和操作。

5. infrastructure

基础设施是构建应用需要用到的基础设施,基础设施主要包括日志,数据库,缓存等外部第三方被调系统或应用接口,是系统可以使用的基础设施的集合。

6. binding

binding是一种机制,围绕应用将API,基础设施以及领域进行绑定,从而构造领域相关的API的一种手段。

7. tag

7.1 sqlmapping

Tag 说明
- 忽略该字段,不进行持久化(不对应任何数据库表列)
column 显式指定该字段对应的数据库表列,如column:foo
key 该列是否作为逻辑键(实际到底哪个字段为键,是由DataContainer定义确定的)使用,如果一个结构的多个字段使用了key,这几个字段将被作为联合键使用
notUpdate 不对该列进行更新操作
updateClear 允许将该列清空为零值
aes 进行aes加密并传递aes的密钥,密钥长度为32字节,不能包含';',也不能以'作为开始和结尾字符
joinWith 字段如果是[]string,可以指定join使用的分隔符,不能包含';',默认是'::',如果使用特殊字符,如'\n','\t'等,需要使用''包含分隔符,也就是说,分隔符不能使用''
trim 字段如果是string,可以指定需要trim的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimPrefix 字段如果是string,可以指定需要trim前缀的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimSuffix 字段如果是string,可以指定需要trim后缀的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符

7.2 sqlresult

Tag 说明
- 忽略该字段,不进行持久化(不对应任何数据库表列)
column 显式指定该字段对应的数据库表列,如column:foo
timeLayout 按照给定的时间格式化字符串格式化时间
aes 进行aes加密并传递aes的密钥,密钥长度为32字节,不能包含';',也不能以'作为开始和结尾字符
splitWith 字段如果是[]string,可以指定split使用的分隔符,不能包含';',默认是'::',如果使用特殊字符,如'\n','\t'等,需要使用''包含分隔符,也就是说,分隔符不能使用''
trim 字段如果是string,可以指定需要trim的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimPrefix 字段如果是string,可以指定需要trim前缀的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimSuffix 字段如果是string,可以指定需要trim后缀的字符,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符

7.3 assign

Tag 说明
- 忽略该字段,不使用该字段赋值
toPackage 要赋值到的字段的结构所在的包路径,要与结构反射Type的PkgPath()返回值一致
toStruct 要赋值到的字段的结构所在的结构名称,要与结构反射Type的Name()返回值一致
toField 要赋值到的结构字段名
timeLayout 将时间字符串赋值给时间字段(time.Time)或将时间字段(time.Time)赋值给时间字符串使用的layout
joinWith 将[]string类型字段赋值给string类型字段时join使用的分隔符,不能包含';',默认是'::',如果使用特殊字符,如'\n','\t'等,需要使用''包含分隔符,也就是说,分隔符不能使用''
splitWith 将string类型字段赋值给[]string类型字段时split使用的分隔符,不能包含';',默认是'::',如果使用特殊字符,如'\n','\t'等,需要使用''包含分隔符,也就是说,分隔符不能使用''
trim 字段如果是string,可以指定需要trim的字符,trim后赋值,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimPrefix 字段如果是string,可以指定需要trim前缀的字符,trim前缀后赋值,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符
trimSuffix 字段如果是string,可以指定需要trim后缀的字符,trim后缀后赋值,不能包含';',如果使用特殊字符,如'\n','\t'等,需要使用''包含,不能以'作为开始和结尾字符

7.3 check

check封装了validator包,在validator包基础上扩展了自己的tag

Tag 说明
timenotzero 判断time不为zero

8. 便捷包

便捷包主要为了简化开发,一般均以可配置的方式定义方法,提供服务和网关两方面的便捷包,搭配使用。目前支持的便捷包主要有以下几个:

名称 说明
pass_through 仅支持网关,转发/直通
entity_crud 实体的增删改查
value_object_crud 值对象增删查
one2one 一对一关联
one2many 一对多
many2many 多对多
remote 关联一方实体定义不在本服务中,网关上复用many2many的即可

9. 成熟领域

成熟领域是设计相对成熟的领域,成熟领域的会实现服务上的调用接口和网关开放接口两部分逻辑。服务调用接口在convenient/domain包中,网关开放接口在convenient/domain_gateway包中。

9.1 configuration

实现了配置相关的增删查接口

9.2 sql_executor

实现了SQL执行接口和SQL执行日志查询接口