GoWS
Framework pour construction API en golang.
(http router based on trie tree)
https://dev.to/bmf_san/introduction-to-url-router-from-scratch-with-golang-3p8j
Features
- Easy to use
- Lightweight
- Fully compatible with net/http
- No external dependencies
- Support named parameters with an optional regular expression
- Support middlewares
- Support db
Install
go get -u gitlab.com/greg198584/gows
Get Started
- Dans le repertoire de votre projet crée dossier et fichier suivant
mkdir config
mkdir controller
touch config/db.json
touch config/http.json
touch config/routes.json
touch controller/main_controller.go
touch main.go
Main controller
controller/main_controller.go
package controller
import (
"gitlab.com/greg198584/gows/controller"
"gitlab.com/greg198584/gows/db"
"gitlab.com/greg198584/gows/router"
"gitlab.com/greg198584/gows/tools"
)
type MainController struct {
*router.Context
M controller.MainController
}
func (mc *MainController) OnCreate() (err error) {
mc.M.Connectors, err = db.Init(mc)
return
}
func (mc *MainController) OnFinish() (err error) {
mc.M.CloseConnexion()
return
}
func (mc *MainController) GetUserID() *int64 {
JwtData := mc.GetContextData("Jwt").(map[string]interface{})
return tools.ToInt(JwtData["id"])
}
func (mc *MainController) RetError(StatusCode int, Msg string) {
mc.JSON(StatusCode, router.SetError(StatusCode, Msg))
return
}
Config connector sql
config/db.json
{
"default_connector": {
"master": {
"host": "",
"user": "",
"password": "",
"port": 3306,
"database": "",
"timeout": 60000,
"driver": "mysql",
"locale": "Europe/Paris"
},
"slave": {
"host": "",
"user": "",
"password": "",
"port": 3306,
"database": "",
"timeout": 60000,
"driver": "mysql",
"locale": "Europe/Paris"
},
"dev" : {
"host": "",
"user": "",
"password": "",
"port": 3306,
"database": "",
"timeout": 60000,
"driver": "mysql",
"locale": "Local"
}
}
}
Config route
config/routes.json
- Supports these http methods
GET/POST/PUT/PATCH/DELETE/OPTIONS
- Scopes: ( gestion des droits sur les routes en specifiant les scopes )
[
{
"path": "GET /test",
"handler": "Test.ControllerTest"
},
{
"path": "GET /test/2/:id",
"handler": "Test.ControllerTest2"
}
]
Config http
config/http.json
{
"listen": "80",
"path": "",
"timeout": 1000,
"jwt_path": "./jwt",
"jwt_key": "4A7D7A566E793A552F5874372B36545029776622634607157342E664B2F22397",
"jwt_iv": "25B76732B736674A50A633F777D4C234",
"post_max_size": 1048576,
"log_namespace":"*",
"log_level":"debug,warning,info,error",
"log_verbose": true,
"middleware": [
{
"ResponseTime": {
"render": "ms"
}
},
{
"TimeOut": {
"value": 4
}
},
"Helmet",
{
"Jwt": {
"bypass": [
"GET /test"
]
}
}
]
}
Usage
Controller
- Pour exemple créer un fichier pour votre controller dans le dossier controller.
touch controller/test.go
Usage DB exemple
package controller
import (
"net/http"
)
func (t *TestDB) Get() (err error) {
type test struct {
Value string `json:"test_value"`
}
var data test
t.M.Conn, _ = t.M.Connectors.Master.GetCnx()
t.M.Results, err = t.M.Conn.QueryContext(t.Context, `query`)
for t.M.results.Next() {
_ = t.M.results.Scan(
&data.Value,
)
}
t.JSON(http.StatusOK, data)
return
}
GET and param
- ajouter à routes.json -> GET /test/:id ( exemple )
package controller
import (
"net/http"
)
type TestData3 struct {
Id string `json:"id"`
}
type Test struct {
*MainController
}
func (mc *MainController) Test() *Test {
return new(Test)
}
func (t *Test) ControllerTest() (err error) {
id := t.GetParam("id")
test := TestData3{
Id: id,
}
t.JSON(http.StatusOK, test)
return
}
ContextData
- Exemple utilisation ContextData pour stocker des variable ou GET des variables
package controller
import (
"net/http"
)
type TestData struct {
Test1 string `json:"test1"`
Test2 string `json:"test2"`
Context1 interface{} `json:"context1"`
Context2 interface{} `json:"context2"`
}
type TestData2 struct {
UserID *int64 `json:"user_id"`
}
type Test struct {
*MainController
}
func (mc *MainController) Test() *Test {
return new(Test)
}
func (t *Test) ControllerTest() (err error) {
t.SetContextData("context_1", 1)
t.SetContextData("context_2", "context_string")
test := TestData{
Test1: "coucou_1_1",
Test2: "coucou_2_2",
Context1: t.GetContextData("context_1"),
Context2: t.GetContextData("context_2"),
}
t.JSON(http.StatusOK, test)
return
}
POST et body ( POST /test)
package controller
import (
"net/http"
)
type Test struct {
*MainController
}
func (mc *MainController) Test() *Test {
return new(Test)
}
func (t *Test) ControllerTest(payload struct {
Body struct {
Data1 string `json:"data_1" validate:"required"`
Data2 string `json:"data_2" validate:"required"`
} `type:"json" validate:"required"`
}) (err error) {
t.JSON(http.StatusOK, payload.Body)
return
}
Meme exemple avec structure exterieur
type GBody struct {
Data1 string `json:"data_1" validate:"required"`
Data2 string `json:"data_2" validate:"required"`
}
func (t *Test) ControllerTest(payload struct {
Body GBody `type:"json" validate:"required"`
}) (err error) {
t.JSON(http.StatusOK, payload.Body)
return
}
Middlewares
Supports middlewares.
package middlewares
import (
"gitlab.com/greg198584/gows/router"
)
func Exemple() func(h router.Handler) router.Handler {
return func(h router.Handler) router.Handler {
return router.HandlerFunc(func(c *router.Context) (err error) {
c.SetContextData("exemple", "middleware_exemple")
return h.Next(c)
})
}
}
Start API
main.go
main.go
package main
import (
"gitlab.com/greg198584/gows/_examples/controller"
"gitlab.com/greg198584/gows/logger"
"gitlab.com/greg198584/gows/middlewares"
"gitlab.com/greg198584/gows/router"
"os"
)
func main() {
err := router.New(&controller.MainController{}).
AddMiddleware("Jwt", middlewares.Jwt).
Listen()
if err != nil {
logger.GetLog("main_exemple").Error(err.Error())
os.Exit(1)
}
}
CFG_PATH=./config/ ENV=DEV go run main.go