github.com/godaddy-x/freego@v1.0.156/README.md (about)

     1  # freego
     2  High performance secure GRPC/ORM/NODE framework
     3  
     4  #### 1. Create simple HTTP/NODE demo
     5  ```
     6  type MyWebNode struct {
     7  	node.HttpNode
     8  }
     9  
    10  func (self *MyWebNode) pubkey(ctx *node.Context) error {
    11  	return self.Text(ctx, "hello world!!!")
    12  }
    13  
    14  func NewHTTP() *MyWebNode {
    15  	var my = &MyWebNode{}
    16  	my.AddJwtConfig(jwt.JwtConfig{
    17  		TokenTyp: jwt.JWT,
    18  		TokenAlg: jwt.HS256,
    19  		TokenKey: "123456" + utils.CreateLocalSecretKey(12, 45, 23, 60, 58, 30),
    20  		TokenExp: jwt.TWO_WEEK,
    21  	})
    22  	my.AddCacheAware(func(ds ...string) (cache.Cache, error) {
    23  		return local, nil
    24  	})
    25  	return my
    26  }
    27  
    28  func main()  {
    29  	my := NewHTTP()
    30  	my.EnableECC(true) // use ecc, default rsa
    31  	my.GET("/pubkey", my.pubkey, &node.RouterConfig{Guest: true})
    32  	my.StartServer(":8090")
    33  }
    34  ```
    35  
    36  
    37  #### 2. Create plugin filter chain
    38  #### You can implement any pre and post operations, and configure `MatchPattern` parameter to apply the specified method
    39  
    40  ```
    41  // default filters
    42  var filterMap = map[string]*FilterObject{
    43  	GatewayRateLimiterFilterName: {Name: GatewayRateLimiterFilterName, Order: -100, Filter: &GatewayRateLimiterFilter{}},
    44  	ParameterFilterName:          {Name: ParameterFilterName, Order: -90, Filter: &ParameterFilter{}},
    45  	SessionFilterName:            {Name: SessionFilterName, Order: -80, Filter: &SessionFilter{}},
    46  	UserRateLimiterFilterName:    {Name: UserRateLimiterFilterName, Order: -70, Filter: &UserRateLimiterFilter{}},
    47  	RoleFilterName:               {Name: RoleFilterName, Order: -60, Filter: &RoleFilter{}},
    48  	ReplayFilterName:             {Name: ReplayFilterName, Order: -50, Filter: &ReplayFilter{}},
    49  	PostHandleFilterName:         {Name: PostHandleFilterName, Order: math.MaxInt, Filter: &PostHandleFilter{}},
    50  	RenderHandleFilterName:       {Name: RenderHandleFilterName, Order: math.MinInt, Filter: &RenderHandleFilter{}},
    51  }
    52  
    53  type NewPostFilter struct{}
    54  
    55  func (self *NewPostFilter) DoFilter(chain node.Filter, ctx *node.Context, args ...interface{}) error {
    56  	ctx.AddStorage("httpLog", node.HttpLog{Method: ctx.Path, LogNo: utils.GetSnowFlakeStrID(), CreateAt: utils.UnixMilli()})
    57  	if err := chain.DoFilter(chain, ctx, args...); err != nil {
    58  		return err
    59  	}
    60  	v := ctx.GetStorage("httpLog")
    61  	if v == nil {
    62  		return utils.Error("httpLog is nil")
    63  	}
    64  	httpLog, _ := v.(node.HttpLog)
    65  	httpLog.UpdateAt = utils.UnixMilli()
    66  	httpLog.CostMill = httpLog.UpdateAt - httpLog.CreateAt
    67  	return nil
    68  }
    69  
    70  func NewHTTP() *MyWebNode {
    71  	var my = &MyWebNode{}
    72  	my.AddJwtConfig(jwt.JwtConfig{
    73  		TokenTyp: jwt.JWT,
    74  		TokenAlg: jwt.HS256,
    75  		TokenKey: "123456" + utils.CreateLocalSecretKey(12, 45, 23, 60, 58, 30),
    76  		TokenExp: jwt.TWO_WEEK,
    77  	})
    78  	my.AddCacheAware(func(ds ...string) (cache.Cache, error) {
    79  		return local, nil
    80  	})
    81  	my.AddFilter(&node.FilterObject{Name: "NewPostFilter", Order: 100, Filter: &NewPostFilter{}})
    82  	return my
    83  }
    84  
    85  // Benchmark test 
    86  goos: darwin
    87  goarch: amd64
    88  cpu: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
    89  BenchmarkPubkey
    90  BenchmarkPubkey-8          14770             80893 ns/op             515 B/op          1 allocs/op
    91  BenchmarkPubkey-8          14908             79999 ns/op             515 B/op          1 allocs/op
    92  BenchmarkPubkey-8          15063             79425 ns/op             514 B/op          1 allocs/op
    93  BenchmarkPubkey-8          15031             82307 ns/op             514 B/op          1 allocs/op
    94  BenchmarkPubkey-8          14925             80306 ns/op             515 B/op          1 allocs/op
    95  BenchmarkPubkey-8          15015             79758 ns/op             515 B/op          1 allocs/op
    96  BenchmarkPubkey-8          15133             79156 ns/op             515 B/op          1 allocs/op
    97  BenchmarkPubkey-8          15070             83157 ns/op             515 B/op          1 allocs/op
    98  BenchmarkPubkey-8          14887             79710 ns/op             517 B/op          1 allocs/op
    99  BenchmarkPubkey-8          15061             79666 ns/op             516 B/op          1 allocs/op
   100  ```
   101  
   102  #### 3. Create JWT&ECC login demo
   103  
   104  ``` see @http_test.go
   105  // Benchmark test 
   106  goos: windows
   107  goarch: amd64
   108  pkg: github.com/godaddy-x/freego
   109  cpu: 12th Gen Intel(R) Core(TM) i5-12400F
   110  BenchmarkRSALogin
   111  BenchmarkRSALogin-12                4058            293012 ns/op
   112  PASS
   113  ```
   114  
   115  #### 4. Create simple ORM demo
   116  
   117  ```
   118  func initMysqlDB() {
   119  	conf := sqld.MysqlConfig{}
   120  	if err := utils.ReadLocalJsonConfig("resource/mysql.json", &conf); err != nil {
   121  		panic(utils.AddStr("读取mysql配置失败: ", err.Error()))
   122  	}
   123  	new(sqld.MysqlManager).InitConfigAndCache(nil, conf)
   124  	fmt.Println("init mysql success")
   125  }
   126  
   127  func initMongoDB() {
   128  	conf := sqld.MGOConfig{}
   129  	if err := utils.ReadLocalJsonConfig("resource/mongo.json", &conf); err != nil {
   130  		panic(utils.AddStr("读取mongo配置失败: ", err.Error()))
   131  	}
   132  	new(sqld.MGOManager).InitConfigAndCache(nil, conf)
   133  	fmt.Println("init mongo success")
   134  }
   135  
   136  func init() {
   137      sqld.ModelDriver(
   138  	&OwWallet{},
   139      )
   140      initMongoDB()
   141      initMysqlDB()
   142  }
   143  
   144  func TestMysqlUpdates(t *testing.T) {
   145      // db, err := sqld.NewMongo(sqld.Option{OpenTx: true})
   146  	db, err := sqld.NewMysql(sqld.Option{OpenTx: true})
   147  	if err != nil {
   148  		panic(err)
   149  	}
   150  	defer db.Close()
   151  	o1 := OwWallet{
   152  		Id:    123,
   153  		AppID: "123",
   154  	}
   155  	o2 := OwWallet{
   156  		Id:    1234,
   157  		AppID: "1234",
   158  	}
   159  	if err := db.Update(&o1, &o2); err != nil {
   160  		panic(err)
   161  	}
   162  }
   163  
   164  func TestMysqlFind(t *testing.T) {
   165      // db, err := sqld.NewMongo()
   166  	db, err := sqld.NewMysql()
   167  	if err != nil {
   168  		panic(err)
   169  	}
   170  	defer db.Close()
   171  	sql := sqlc.M().Fields("rootPath").Eq("id", 1).Between("index", 10, 50).Gte("index", 30).Like("name", "test").Or(sqlc.M().Eq("id", 12), sqlc.M().Eq("id", 13))
   172  	wallet := OwWallet{}
   173  	if err := db.FindOne(sql, &wallet); err != nil {
   174  		panic(err)
   175  	}
   176  }
   177  ```
   178  
   179  #### 5. Create simple Consul&GRPC demo
   180  
   181  ```
   182  func init() {
   183  	client := &rpcx.GRPCManager{}
   184  	client.CreateJwtConfig(APPKEY)
   185  	client.CreateAppConfigCall(func(appid string) (rpcx.AppConfig, error) {
   186  		if appid == APPKEY {
   187  			return rpcx.AppConfig{Appid: APPID, Appkey: APPKEY}, nil
   188  		}
   189  		return rpcx.AppConfig{}, utils.Error("appid invalid")
   190  	})
   191  	client.CreateRateLimiterCall(func(method string) (rate.Option, error) {
   192  		return rate.Option{}, nil
   193  	})
   194  	client.CreateServerTLS(rpcx.TlsConfig{
   195  		UseMTLS:   true,
   196  		CACrtFile: "./rpcx/cert/ca.crt",
   197  		KeyFile:   "./rpcx/cert/server.key",
   198  		CrtFile:   "./rpcx/cert/server.crt",
   199  	})
   200  	client.CreateClientTLS(rpcx.TlsConfig{
   201  		UseMTLS:   true,
   202  		CACrtFile: "./rpcx/cert/ca.crt",
   203  		KeyFile:   "./rpcx/cert/client.key",
   204  		CrtFile:   "./rpcx/cert/client.crt",
   205  		HostName:  "localhost",
   206  	})
   207  	client.CreateAuthorizeTLS("./rpcx/cert/server.key")
   208  }
   209  
   210  // grpc server
   211  func TestConsulxGRPCServer(t *testing.T) {
   212  	objects := []*rpcx.GRPC{
   213  		{
   214  			Address: "localhost",
   215  			Service: "PubWorker",
   216  			Tags:    []string{"ID Generator"},
   217  			AddRPC:  func(server *grpc.Server) { pb.RegisterPubWorkerServer(server, &impl.PubWorker{}) },
   218  		},
   219  	}
   220  	rpcx.RunServer("", true, objects...)
   221  }
   222  
   223  // grpc client
   224  func TestConsulxGRPCClient(t *testing.T) {
   225  	rpcx.RunClient(APPID)
   226  	conn, err := rpcx.NewClientConn(rpcx.GRPC{Service: "PubWorker", Cache: 30})
   227  	if err != nil {
   228  		panic(err)
   229  	}
   230  	defer conn.Close()
   231  	res, err := pb.NewPubWorkerClient(conn.Value()).GenerateId(conn.Context(), &pb.GenerateIdReq{})
   232  	if err != nil {
   233  		panic(err)
   234  	}
   235  	fmt.Println("call result: ", res)
   236  }
   237  
   238  // grpc client benchmark test
   239  func BenchmarkGRPCClient(b *testing.B) {
   240  	rpcx.RunClient(APPID)
   241  	b.StopTimer()
   242  	b.StartTimer()
   243  	for i := 0; i < b.N; i++ { //use b.N for looping
   244  		conn, err := rpcx.NewClientConn(rpcx.GRPC{Service: "PubWorker", Cache: 30})
   245  		if err != nil {
   246  			return
   247  		}
   248  		_, err = pb.NewPubWorkerClient(conn.Value()).GenerateId(conn.Context(), &pb.GenerateIdReq{})
   249  		if err != nil {
   250  			return
   251  		}
   252  		conn.Close()
   253  	}
   254  }
   255  
   256  BenchmarkGRPCClient-40              11070            212487 ns/op
   257  ```
   258