Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alimy/mir
Mir is a toolkit for register method handler to http engine router(eg: gin,echo,iris,mux,httprouter) use struct tag info.
https://github.com/alimy/mir
echo gin go go-chi go-mir golang hertz httprouter iris macaron mux web
Last synced: 22 days ago
JSON representation
Mir is a toolkit for register method handler to http engine router(eg: gin,echo,iris,mux,httprouter) use struct tag info.
- Host: GitHub
- URL: https://github.com/alimy/mir
- Owner: alimy
- License: apache-2.0
- Created: 2019-01-10T15:46:16.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2024-05-21T12:22:53.000Z (6 months ago)
- Last Synced: 2024-05-21T13:39:47.937Z (6 months ago)
- Topics: echo, gin, go, go-chi, go-mir, golang, hertz, httprouter, iris, macaron, mux, web
- Language: Go
- Homepage: https://alimy.github.io/mir/
- Size: 5.3 MB
- Stars: 81
- Watchers: 4
- Forks: 13
- Open Issues: 3
-
Metadata Files:
- Readme: README-en.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[![Go](https://github.com/alimy/mir/actions/workflows/go.yml/badge.svg)](https://github.com/alimy/mir/actions/workflows/go.yml)
[![GoDoc](https://godoc.org/github.com/alimy/mir?status.svg)](https://pkg.go.dev/github.com/alimy/mir/v4)
[![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?logo=sourcegraph)](https://sourcegraph.com/github.com/alimy/mir)Mir is a toolkit to develop RESTful API backend service like develop service of gRPC. It adapt some HTTP framework sush as [Gin](https://github.com/gin-gonic/gin), [Chi](https://github.com/go-chi/chi), [Hertz](https://github.com/cloudwego/hertz), [Echo](https://github.com/labstack/echo), [Iris](https://github.com/kataras/iris), [Fiber](https://github.com/gofiber/fiber), [Macaron](https://github.com/go-macaron/macaron), [Mux](https://github.com/gorilla/mux), [httprouter](https://github.com/julienschmidt/httprouter)。
### Tutorials
* Generate a simple template project
```bash
% go install github.com/alimy/mir/mirc/v4@latest
% mirc new -h
create template projectUsage:
mirc new [flags]Flags:
-d, --dst string genereted destination target directory (default ".")
-h, --help help for new
--mir string mir replace package name or place
-p, --pkg string project's package name (default "github.com/alimy/mir-example")
-s, --style string generated engine style eg: gin,chi,mux,hertz,echo,iris,fiber,fiber-v2,macaron,httprouter (default "gin")% mirc new -d example
% tree example
example
.
|-- Makefile
|-- README.md
|-- go.mod
|-- go.sum
|-- main.go
|-- mirc
| |-- auto
| | `-- api
| | |-- site.go
| | |-- v1
| | | `-- site.go
| | `-- v2
| | `-- site.go
| |-- gen.go
| `-- routes
| |-- site.go
| |-- v1
| | `-- site.go
| `-- v2
| `-- site.go
`-- servants
|-- core.go
|-- servants.go
|-- site.go
|-- site_v1.go
`-- site_v2.go% cd example
% make generate
% make run
```
* RESTful API define:
```go
// file: mirc/routes.gopackage routes
import (
. "github.com/alimy/mir/v4"
. "github.com/alimy/mir/v4/engine"
)func init() {
AddEntry(new(User))
}type LoginReq struct {
Name string `json:"name"`
Passwd string `json:"passwd"`
}type LoginResp struct {
JwtToken string `json:"jwt_token"`
}// User user interface info
type User struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
Login func(Post, LoginReq) LoginResp `mir:"/login/"`
Logout func(Post) `mir:"/logout/"`
}
```* Stub source code generatee automatic:
```go
// file: mirc/auto/api/routes.go// Code generated by go-mir. DO NOT EDIT.
// versions:
// - mir v4.0.0package routes
import (
"net/http""github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
)type _binding_ interface {
Bind(*gin.Context) mir.Error
}type _render_ interface {
Render(*gin.Context)
}type _default_ interface {
Bind(*gin.Context, any) mir.Error
Render(*gin.Context, any, mir.Error)
}type LoginReq struct {
Name string `json:"name"`
Passwd string `json:"passwd"`
}type LoginResp struct {
JwtToken string `json:"jwt_token"`
}type User interface {
_default_// Chain provide handlers chain for gin
Chain() gin.HandlersChainLogin(*gin.Context, *LoginReq) (*LoginResp, mir.Error)
Logout(*gin.Context) mir.ErrormustEmbedUnimplementedUserServant()
}// UnimplementedUserServant can be embedded to have forward compatible implementations.
type UnimplementedUserServant struct {
}// RegisterUserServant register User servant to gin
func RegisterUserServant(e *gin.Engine, s User) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)// register routes info to router
router.Handle("POST", "/login/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req := new(LoginReq)
if err := s.Bind(c, req); err != nil {
s.Render(c, nil, err)
return
}
resp, err := s.Login(req)
s.Render(c, resp, err)
})
router.Handle("POST", "/logout/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.Render(c, nil, s.Logout(c))
})
}func (UnimplementedUserServant) Chain() gin.HandlersChain {
return nil
}func (UnimplementedUserServant) Login(c *gin.Context, req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}func (UnimplementedUserServant) Logout(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}func (UnimplementedUserServant) mustEmbedUnimplementedUserServant() {}
```* API interface implement:
```go
// file: servants/user.gopackage servants
import (
"github.com/alimy/mir-example/v4/mirc/auto/api"
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
)type baseSrv struct{}
func (baseSrv) Bind(c *gin.Context, obj any) mir.Error {
if err := c.ShouldBind(obj); err != nil {
mir.NewError(http.StatusBadRequest, err)
}
return nil
}func (baseSrv) Render(c *gin.Context, data any, err mir.Error) {
if err == nil {
c.JSON(http.StatusOK, data)
} else {
c.JSON(err.StatusCode(), err.Error())
}
}type userSrv struct {
baseSrvapi.UnimplementedUserServant
}func newUserSrv() api.Site {
return &userSrv{}
}
```* Service register:
```go
// file: servants/servants.gopackage servants
import (
"github.com/alimy/mir-example/v4/mirc/auto/api"
"github.com/gin-gonic/gin"
)// RegisterServants register all the servants to gin.Engine
func RegisterServants(e *gin.Engine) {
api.RegisterUserServant(e, newUserSrv())
// TODO: some other servant to register
}
```* App start:
```go
// file: main.gopackage main
import (
"log""github.com/alimy/mir-example/v4/servants"
"github.com/gin-gonic/gin"
)func main() {
e := gin.Default()// register servants to gin
servants.RegisterServants(e)// start servant service
if err := e.Run(); err != nil {
log.Fatal(err)
}
}
```### Projects that used [go-mir](https://github.com/alimy/mir)
* [examples](examples) - a demo example to describe how to use [Mir](https://github.com/alimy/mir) to develop RESTful API backend service quickly.
* [paopao-ce](https://github.com/rocboss/paopao-ce/tree/dev) - A artistic "twitter like" community built on gin+zinc+vue+ts.