End of the year these days own research and development of a gateway project design and development based in Go, and its open source, you need a small partner, please click: [ Github Address ] independent download, README has fairly detailed explanation document, I do not like the front, so it does not find an open source background page access, but provides the corresponding data is added interface, the interface address in the project [ DOC ] explained, the table structure design also [ tABLE ] in a very Detailed explanation.
Besides, I feel there is another tool to facilitate: [ renewed request ]
Caution :
- Project dependencies are required, its configuration is stored in [ conf ] Configuration Center
- The need for strict control in accordance with the data structure and data in accordance with MongoDB TABLE, or can not use normal
- Watching feel good, oh must ✨✨✨✨
Project Dependencies :
- Gin framework
- Redis
- MongoDB
Realize the functions :
- Routing forwarding, including timeout settings (basic functions GET / POST)
- Multi-IP / domain configuration
- Routing dns (only supported in rotation)
- Limiting request
- Data caching
- Fault-tolerant request
- Unified sound (in development)
Design goals :
- Modular
- Placement of
Entrance: main function, in order to facilitate the subsequent expansion, so could not spare
main Package Import ( "GW / route" ) // main function is nothing to say, try to clean, convenient subsequent module adds FUNC main () { R & lt: = route.Route () r.Run ( ": 1323") }
Route: The route took separate, separate front and rear ends of the route
route Package Import ( "GW / route / ADMIN" "GW / route / API" "github.com/gin-gonic/gin" ) // set the call routing FUNC the Route () * {gin.Engine R & lt: = gin.Default () // external call routing api.Route (R & lt) // backend interface call routing admin.Route (R & lt) return R & lt }
Background Interface: Provides group and add wg table base interface, so that the project can run up
ADMIN Package Import ( "GW / PKG / ADMIN" "github.com/gin-gonic/gin" ) FUNC the Route (R & lt gin.Engine *) { // access route forwarding interface r.POST ( "/ req / add / API ", admin.Add) // API interface to dynamically generate forwarding table Add r.POST (" / REQ / the Add / Group ", admin.AddGroup) }
Front Interface: Dynamic Routing cyclic group (Group), which was added to the obfuscated routing configuration in order to solve the subsequent increase in the configuration table need to restart wg
package api import ( "fmt" "gw/pkg/api" "gw/library" "gw/pkg/middle" "github.com/gin-gonic/gin" ) func Route(r *gin.Engine) { list, err := library.Group("group") if err != nil { panic(fmt.Sprintf("Api Route Was Wrong Err Was %s", err)) } //动态加载路由,根据mongoDB中的path加载 for _, v := range list { pth := v.Group r.Any(fmt.Sprintf("%s%s", pth, "*action"), api.Run, middle.Body()) } }
Execute program entry: This entry is the entry of the system logic, a better way is currently not thought
Package Penalty for API Import ( "fmt" "NET / HTTP" "Time" "gw / conf" "gw / Library" "gw / pkg / ds" "gw / pkg / dy" "gw / pkg / fw" "gw / util " " github.com/gin-gonic/gin " ) // entry function FUNC the Run (C * gin.Context) { T: = time.NewTimer (conf.RequestTimeOut * time.Second) // set Global var G GLB GLB = the make .Rch (Chan String) glb.Ech = the make (Chan error) Go FUNC (gin.Context C *, G * GLB) { glb.RequestTime util.GetTime = () // setting request access if err: glb.SetInfo = (C);! {ERR = nil glb.Ech <- ERR return } // Fault Tolerance Decay: = {dy.Decay the Open: glb.Md.Decay, DecayTime: glb.Md.DecayTime, of Ctx: C, } decayBody: = decay.Start () ! = IF decayBody "" { glb.Rch <- decayBody return } // Get url to access DNS: = {ds.Dns Ds: glb.Md.Dns, Pth is: glb.Md.To, of Ctx: C, } dns.GetRestUrl () glb.To = dns.To GLB. = dns.Query Query // check flow flow: = {fw.Flow the Path: glb.To, the Num: glb.Md.Flow, } IF ERR:! = flow.Check (); ERR = nil { glb.Ech < - ERR return } // initiation request HP: = {library.HttpRequest Method,: glb.Md.Method, the To: glb.To, Query: glb.Query, Out: glb.Md.Timeout, CacheTime: glb.Md.CacheTime, } // initiating a request body, ERR: = hp.Http () IF ERR = nil {! glb.Ech <- ERR return } // write context currently used for fault tolerance c.Set ( "requestBody", body) glb.Rch < - body } (C, & GLB) SELECT { Case Rch: = <-glb.Rch: c.String (http.StatusOK, Rch) Case ECH: = <-glb.Ech: c.String (http.StatusInternalServerError, FMT. Sprintln (ECH)) Case <-tC: c.String (http.StatusNotFound, "Request Time OUT") } t.Stop() }
From the above code can be seen in the general project design, the specific function code is no longer a separate map, you can get the code look after, project design very simple, very easy to expand