Skip to content
keepchenPublic

Repository files navigation

sailboat-solid

Go CodeQL golangci-lint codecov Dependabot Status Snyk Security LICENSE: MIT

LATEST_VERSION

English | 简体中文 | 日本語

Whats the go-sail?

go-sail is a lightweight progressive web framework implemented using Go language. It is not the product of reinventing the wheel, but stands on the shoulders of giants and integrates existing excellent components to help users build stable and reliable services in the simplest way. As its name suggests, you can regard it as the beginning of your own journey in the Golang ecosystem. go-sail will help you start lightly and set sail.

How to use

go version >= 1.23

go get -u github.com/keepchen/go-sail/v3

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/keepchen/go-sail/v3/sail"
    "github.com/keepchen/go-sail/v3/sail/config"
)

var (
    conf = &config.Config{}
    registerRoutes = func(ginEngine *gin.Engine) {
        ginEngine.GET("/hello", func(c *gin.Context){
            c.String(http.StatusOK, "%s", "hello, world!")
        })
    }
)

func main() {
    sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}

Console screenshot after launched like this:

launch.png

Examples

Configuration

parseFn := func(content []byte, viaWatch bool){
    fmt.Println("config content: ", string(content))
    if viaWatch {
        //reload config...
    }
}
etcdConf := etcd.Conf{
	Endpoints: []string{""},
	Username: "",
	Password: "",
}
key := "go-sail.config.yaml"

sail.Config(parseFn).ViaEtcd(etcdConf, key).Parse(parseFn)

Log trace

func UserRegisterSvc(c *gin.Context) {
  ...
  sail.LogTrace(c).Warn("log something...")
  ...
}

JWT authentication

  • Issue token
func UserLoginSvc(c *gin.Context) {
  ...
  uid := "user-1000"
  exp := time.Now().Add(time.Hour * 24).Unix()
  otherFields := map[string]interface{}{
      "nickname": "go-sail",
      "avatar": "https://go-sail.dev/assets/avatar/1.png",
      ...
  }
  ok, token, err := sail.JWT().MakeToken(uid, exp, otherFields)
  ...
}
  • Authentication
func UserInfoSvc(c *gin.Context) {
  ...
  ok, claims, err := sail.JWT().ValidToken(token)
  ...
}

Components

Responder

func UserInfoSvc(c *gin.Context) {
  sail.Response(c).Wrap(constants.ErrNone, resp).Send()
}

Database

  • Read / Write
func UserInfoSvc(c *gin.Context) {
  uid := "user-1000"
  var user models.User
  //READ: query user info
  sail.GetDBR().Where("uid = ?", uid).First(&user)
  ...
  //WRITE: update user info
  sail.GetDBW().Model(&models.User{}).
      Where("uid = ?", uid).
      Updates(map[string]interface{}{
          "avatar": "https://go-sail.dev/assets/avatar/2.png"
      })
}
  • Transaction
func UserInfoSvc(c *gin.Context) {
  uid := "user-1000"
  err := sail.GetDBW().Transaction(func(tx *gorm.DB){
      e1 := tx.Model(&models.User{}).
              Where("uid = ?", uid).
              Updates(map[string]interface{}{
                  "avatar": "https://go-sail.dev/assets/avatar/2.png"
              }).Error
      if e1 != nil {
          return e1
      }
      e2 := tx.Create(&models.UserLoginHistory{
                Uid: uid,
                ...
              }).Error
      return e2
  })
}

Redis

func UserInfoSvc(c *gin.Context) {
  ...
  sail.GetRedis().Set(ctx, "go-sail:userInfo", "user-1000", time.Hour*24).Result()
  ...
}

Password

  • RSA
sail.Password().RSAEncrypt(plaintext, publicKey) // Deprecated: PKCS #1 v1.5 encryption is unsafe. Use EncryptOAEP for new data.

sail.Password().RSADecrypt(encryptedStr, privateKey) // Deprecated: PKCS #1 v1.5 decryption is unsafe. Use DecryptOAEP for OAEP ciphertext.

sail.Password().RSAEncryptOAEP(plaintext, publicKey)

sail.Password().RSADecryptOAEP(encryptedStr, privateKey)
  • Bcrypt
sail.Password().BcryptHashMake(plaintext)

sail.Password().BcryptHashCheck(plaintext, hash)
  • Argon2
sail.Password().Argon2HashMake(plaintext)

sail.Password().Argon2HashCheck(plaintext, hash)
  • Aes
sail.Password().AesGCMEncrypt(plaintext, key)

sail.Password().AesGCMDecrypt(ciphertext, key)
  • SM4
sail.Password().SM4GCMEncrypt(plaintext, key)

sail.Password().SM4GCMDecrypt(ciphertext, key)

Task schedule

  • Interval
func TodoSomething() {
  fn := func() { ... }
  sail.Schedule("todoSomething", fn).Daily()
}
  • Linux Crontab style
func TodoSomething() {
  fn := func() { ... }
  sail.Schedule("todoSomething", fn).RunAt("*/5 * * * *")
}
  • Race detection
func TodoSomething() {
  fn := func() { ... }
  sail.Schedule("todoSomething", fn).Withoutoverlapping().RunAt("*/5 * * * *")
}

Distributed lock

func UpdateUserBalance() {
  if !sail.RedisLocker().TryLock(key) {
      return false
  }
  defer sail.RedisLocker().Unlock(key)
  ...
}

Documentation

https://go-sail.dev

Live demo

https://nav.go-sail.dev

Features

  • HTTP Responder
    • Uniform Response Fields
    • Managing HTTP status codes
    • Management business code
  • Components
    • Database
    • Email
    • Jwt
    • Kafka
    • Logger
    • Nacos
    • Etcd
    • Nats
    • Redis
    • Valkey
  • Service Registration and Discovery
    • Nacos
    • Etcd
  • Toolkit
    • Encryption and Decryption
    • File
    • IP
    • String
    • Random number
    • Date and Time
    • ...
  • Log collection and export
    • Local files
    • Exporter
      • Redis
      • Kafka
      • Nats
  • Scheduled Tasks
    • Cancellable
    • Disposable
    • Periodic
    • Linux Crontab style
    • Race Detection
  • Telemetry and Observability
    • Call chain tracing
    • Prometheus
    • Pprof
    • Log Exporter
    • Performance monitor
      • Prometheus
      • Pprof
    • Distributed Quantile Statistics
      • P99
      • P90
      • ...
      • P(N)
  • API error codes
    • Dynamic injection
    • Internationalization
  • Distributed lock based on Redis
    • Blocking
    • None-Blocking
  • API Documentation
    • Redocly
    • Swagger
  • Configuration
    • File
    • Etcd
    • Nacos

Other Plugins

README.md

Benchmark

ulimit -n 65535 && sh run_benchmark.sh

Test results (real HTTP requests)

goos: darwin
goarch: amd64
pkg: github.com/keepchen/go-sail/v3
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkGoSailParallel-12    88252    12898 ns/op    8860 B/op    92 allocs/op
BenchmarkGinParallel-12       96548    11722 ns/op    7187 B/op    82 allocs/op
PASS
ok    github.com/keepchen/go-sail/v3  3.663s

benchmark-result.png

Big Thanks

Thank you to everyone who provided valuable suggestions and comments during the experience and use, as well as provided other kinds of help!

Other

  • PR is welcome: pull request
  • Issue is welcome: issue
  • Thank you for your star if you like this project :)

Use cases

Logo URL Category Industry
fsx120.cn https://fsx120.cn Website Medical
sendflare.com https://sendflare.com Website SaaS
stardots.io https://stardots.io Website SaaS
Piggy (telegram mini-game) https://t.me/PiggyPiggyofficialbot Telegram miniprogram Web3 GameFi
生活好评助手-小程序 - Wechat miniprogram Lifestyle services
FantaGoal - Website Web3 GameFi
WinGoal - Website Web3 GameFi
Pikaster - Website Web3 GameFi

Sponsors

Powered by DartNode - Free VPS for Open Source Secure and Anonymous Temp Mail Service Your All-in-One Image Hosting and Transformation Powerhouse

Star History

Star History Chart

Releases

Used by

Contributors

Languages