|
| 1 | +/* |
| 2 | +Package lars - Library Access/Retrieval System, is a fast radix-tree based, zero allocation, HTTP router for Go. |
| 3 | +
|
| 4 | +Usage |
| 5 | +
|
| 6 | +Below is a simple example, for a full example see here https://github.com/go-playground/lars/blob/master/examples/all-in-one/main.go |
| 7 | +
|
| 8 | + package main |
| 9 | +
|
| 10 | + import ( |
| 11 | + "net/http" |
| 12 | +
|
| 13 | + "github.com/go-playground/lars" |
| 14 | + mw "github.com/go-playground/lars/examples/middleware/logging-recovery" |
| 15 | + ) |
| 16 | +
|
| 17 | + func main() { |
| 18 | +
|
| 19 | + l := lars.New() |
| 20 | + l.Use(mw.LoggingAndRecovery) // LoggingAndRecovery is just an example copy paste and modify to your needs |
| 21 | +
|
| 22 | + l.Get("/", HelloWorld) |
| 23 | +
|
| 24 | + http.ListenAndServe(":3007", l.Serve()) |
| 25 | + } |
| 26 | +
|
| 27 | + // HelloWorld ... |
| 28 | + func HelloWorld(c lars.Context) { |
| 29 | + c.Response().Write([]byte("Hello World")) |
| 30 | +
|
| 31 | + // this will also work, Response() complies with http.ResponseWriter interface |
| 32 | + fmt.Fprint(c.Response(), "Hello World") |
| 33 | + } |
| 34 | +
|
| 35 | +URL Params |
| 36 | +
|
| 37 | + l := l.New() |
| 38 | + l.Get("/user/:id", UserHandler) |
| 39 | + l.Get("/static/*", http.FileServer(http.Dir("static/"))) // serve css, js etc.. c.Param(lars.WildcardParam) will return the |
| 40 | + // remaining path if you need to use it in a custom handler... |
| 41 | +
|
| 42 | + NOTE: Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. |
| 43 | + For example you can not register the patterns /user/new and /user/:user for the same request method at the same time. |
| 44 | + The routing of different request methods is independent from each other. I was initially against this, and this router allowed |
| 45 | + it in a previous version, however it nearly cost me in a big app where the dynamic param value say :type actually could have matched |
| 46 | + another static route and that's just too dangerous, so it is no longer allowed. |
| 47 | +
|
| 48 | +Groups |
| 49 | +
|
| 50 | + ... |
| 51 | + l.Use(LoggingAndRecovery) |
| 52 | + ... |
| 53 | + l.Post("/users/add", ...) |
| 54 | +
|
| 55 | + // creates a group for user + inherits all middleware registered using l.Use() |
| 56 | + user := l.Group("/user/:userid") |
| 57 | + user.Get("", ...) |
| 58 | + user.Post("", ...) |
| 59 | + user.Delete("/delete", ...) |
| 60 | +
|
| 61 | + contactInfo := user.Group("/contact-info/:ciid") |
| 62 | + contactinfo.Delete("/delete", ...) |
| 63 | +
|
| 64 | + // creates a group for others + inherits all middleware registered using l.Use() + adds OtherHandler to middleware |
| 65 | + others := l.Group("/others", OtherHandler) |
| 66 | +
|
| 67 | + // creates a group for admin WITH NO MIDDLEWARE... more can be added using admin.Use() |
| 68 | + admin := l.Group("/admin",nil) |
| 69 | + admin.Use(SomeAdminSecurityMiddleware) |
| 70 | + ... |
| 71 | +
|
| 72 | +Custom Context + Avoid Type Casting / Custom Handlers |
| 73 | +
|
| 74 | + ... |
| 75 | + // MyContext is a custom context |
| 76 | + type MyContext struct { |
| 77 | + *lars.Ctx // a little dash of Duck Typing.... |
| 78 | + } |
| 79 | +
|
| 80 | + // RequestStart overriding |
| 81 | + func (mc *MyContext) RequestStart(w http.ResponseWriter, r *http.Request) { |
| 82 | + mc.Ctx.RequestStart(w, r) // MUST be called! |
| 83 | +
|
| 84 | + // do whatever you need to on request start, db connections, variable init... |
| 85 | + } |
| 86 | +
|
| 87 | + // RequestEnd overriding |
| 88 | + func (mc *MyContext) RequestEnd() { |
| 89 | +
|
| 90 | + // do whatever you need on request finish, reset variables, db connections... |
| 91 | +
|
| 92 | + mc.Ctx.RequestEnd() // MUST be called! |
| 93 | + } |
| 94 | +
|
| 95 | + // CustomContextFunction is a function that is specific to your applications needs that you added |
| 96 | + func (mc *MyContext) CustomContextFunction() { |
| 97 | + // do something |
| 98 | + } |
| 99 | +
|
| 100 | + // newContext is the function that creates your custom context + |
| 101 | + // contains lars's default context |
| 102 | + func newContext(l *lars.LARS) lars.Context { |
| 103 | + return &MyContext{ |
| 104 | + Ctx: lars.NewContext(l), |
| 105 | + } |
| 106 | + } |
| 107 | +
|
| 108 | + // casts custom context and calls you custom handler so you don;t have to type cast lars.Context everywhere |
| 109 | + func castCustomContext(c lars.Context, handler lars.Handler) { |
| 110 | +
|
| 111 | + // could do it in all one statement, but in long form for readability |
| 112 | + h := handler.(func(*MyContext)) |
| 113 | + ctx := c.(*MyContext) |
| 114 | +
|
| 115 | + h(ctx) |
| 116 | + } |
| 117 | +
|
| 118 | + func main() { |
| 119 | +
|
| 120 | + l := lars.New() |
| 121 | + l.RegisterContext(newContext) // all gets cached in pools for you |
| 122 | + l.RegisterCustomHandler(func(*MyContext) {}, castCustomContext) |
| 123 | + l.Use(Logger) |
| 124 | +
|
| 125 | + l.Get("/", Home) |
| 126 | +
|
| 127 | + http.ListenAndServe(":3007", l.Serve()) |
| 128 | + } |
| 129 | +
|
| 130 | + // Home ...notice the receiver is *MyContext, castCustomContext handled the type casting for us |
| 131 | + // quite the time saver if you ask me. |
| 132 | + func Home(c *MyContext) { |
| 133 | +
|
| 134 | + c.CustomContextFunction() |
| 135 | + ... |
| 136 | + } |
| 137 | +
|
| 138 | +Misc |
| 139 | +
|
| 140 | + ... |
| 141 | + // can register multiple handlers, the last is considered the last in the chain and others |
| 142 | + // considered middleware, but just for this route and not added to middleware like l.Use() does. |
| 143 | + l.Get(/"home", AdditionalHandler, HomeHandler) |
| 144 | +
|
| 145 | + // set custom 404 ( not Found ) handler |
| 146 | + l.Register404(404Handler) |
| 147 | +
|
| 148 | + // Redirect to or from ending slash if route not found, default is true |
| 149 | + l.SetRedirectTrailingSlash(true) |
| 150 | +
|
| 151 | + // Handle 405 ( Method Not allowed ), default is false |
| 152 | + l.SetHandle405MethodNotAllowed(false) |
| 153 | +
|
| 154 | + // register custom context |
| 155 | + l.RegisterContext(ContextFunc) |
| 156 | +
|
| 157 | + // Register custom handler type, see util.go https://github.com/go-playground/lars/blob/master/util.go#L62 for example handler creation |
| 158 | + l.RegisterCustomHandler(interface{}, CustomHandlerFunc) |
| 159 | +*/ |
| 160 | +package lars |
0 commit comments