Categorygithub.com/wencan/fastrest
module
0.0.0-20231129005948-e2a80a656c5c
Repository: https://github.com/wencan/fastrest.git
Documentation: pkg.go.dev

# README

fastrest

Go Reference

Go语言RESTful服务通用组件库
Restful服务公共组件库,目的为帮忙快速开发服务程序,尽可能省去与业务无关的重复代码。
可以只使用个别组件,也可以组合起来当“框架”用。

fastrest与常说的“框架”的区别

  • fastrest是一些辅助性质的函数/结构的集合。
  • fastrest不造重复的轮子。
  • fastrest力求足够的简单、开放。

目录

结构体/方法作用说明
restserver/httpserverhttp服务组件一套http服务的辅助组件,需要组合httpmultiplexer一起使用
restserver/httpserver/stdmiddlewareshttp中间件一个http的缓存中间件,支持简单的常见的缓存控制策略
restclient/httpclienthttp客户端组件一套http客户端的辅助组件
restcacheCaching单个数据的缓存中间件缓存流程的胶水逻辑。
基于SentinelGroup解决缓存实效风暴问题。
简单介绍见这里
MCaching批量数据的缓存中间件
restcache/lrucacheLRUCacheLRU缓存存储实现了restcache的缓存存储接口。
基于LRUMap实现。
resterror错误处理
restutils常用工具函数

示例

restserver/httpserver:启动一个HTTP Server

s := NewServer(ctx, &http.Server{
    Addr: "127.0.0.1:28080",
    Handler: ...,
})
addr, err := s.Start(ctx) //  启动监听,开始服务。直至收到SIGTERM、SIGINT信号,或Stop被调用。
fmt.Println("Listen running at:", addr)

s.Stop(ctx) // 结束监听。实际环境应该是内部接收退出信号

<-s.ShutdownNotify()
fmt.Println("Exiting...")
err = s.Wait(ctx) // 等待处理完
fmt.Println("Exited")

restserver/httpserver: 创建一个HTTP Handler

type Request struct {
    Greeting string `schema:"greeting" json:"greeting" validate:"required"`
}
type Response struct {
    Echo string `json:"echo"`
}

var handler http.HandlerFunc = NewGenericsHandler((func(ctx context.Context, req *Request) (*Response, error) {
    // do things

    // output json body
    return &Response{
        Echo: req.Greeting,
    }, nil
}))

fastrest/restserver/httpserver/stdmiddlewares:HTTP缓存中间件

storage := lrucache.NewLRUCache(10000, 10)    // 一般也可能是redis客户端
ttlRange := [2]time.Duration{time.Minute * 4, time.Minute * 6}
cacheMiddleware := NewCacheMiddleware(storage, ttlRange, nil)

var handler http.HandlerFunc = cacheMiddleware(func(w http.ResponseWriter, r *http.Request) {
    // 缓存未命中,才会执行这里
    // ... ...
})

restclient/httpclient: 客户端Get请求

type Request struct {
    Greeting string `schema:"greeting"`
}
type Response struct {
    Echo string `json:"echo"`
}

request := Request{Greeting: "Hi"}
response := Response{}
_ = Get(context.TODO(), &response, s.URL+"/path", request)

restclient/httpclient: 客户端PostJson请求

type Request struct {
    Greeting string `json:"greeting"`
}
type Response struct {
    Echo string `json:"echo"`
}

request := Request{Greeting: "Hi"}
response := Response{}
_ = PostJson(context.TODO(), &response, s.URL+"/path", request)

restcache: 单个数据的缓存

query := func(ctx context.Context, destPtr interface{}, args interface{}) (found bool, err error) {
    // 如果Storage没找到,这里提供
    // 一般是从持久化数据库、服务接口查询
    return true, nil
}

caching := Caching{
    Storage:     lrucache.NewLRUCache(10000, 10), // 一般是redis实现。透明处理业务数据。
    Query:       query,
    TTLRange:    [2]time.Duration{time.Minute * 4, time.Minute * 6},
    SentinelTTL: time.Second,
}

var resp Response
var key = "key"
var args = ?    // 给query函数的参数
found, err := caching.Get(context.TODO(), &resp, key, args)

restcache: 一批数据的缓存

query := func(ctx context.Context, destSlicePtr interface{}, argsSlice interface{}) (missIndexes []int, err error) {
    // 如果Storage没找到,这里提供
    // 一般是从持久化数据库、服务接口查询
    // destSlicePtr为接收结果的切片的指针,argsSlice为入参切片
    // missIndexes是没查到的下标
    return missIndexes, nil
}

mcaching := MCaching{
    MStorage:    lrucache.NewLRUCache(10000, 10), // 一般是redis实现
    MQuery:      query,
    TTLRange:    [2]time.Duration{time.Minute * 4, time.Minute * 6},
    SentinelTTL: time.Second,
}

var keys = []string{......}
var args = ......    // 给query函数的参数切片
var resp []*response
missIndexes, err := mcaching.MGet(context.TODO(), &resp, keys, args)

for _, missIndex := range missIndexes {
    // not found: keys[missIndex]
}

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author