Documentation ¶
Overview ¶
Package siris is a fully-featured HTTP/2 backend web framework written entirely in Google’s Go Language.
Source code and other details for the project are available at GitHub:
https://github.com/go-siris/siris
Installation ¶
The only requirement is the Go Programming Language, at least version 1.8
$ go get -u github.com/go-siris/siris
Example code:
package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) // User is just a bindable object structure. type User struct { Username string `json:"username"` Firstname string `json:"firstname"` Lastname string `json:"lastname"` City string `json:"city"` Age int `json:"age"` } func main() { app := siris.New() // Define templates using the std html/template engine. // Parse and load all files inside "./views" folder with ".html" file extension. // Reload the templates on each request (development mode). app.AttachView(app.HTML("./views", ".html").Reload(true)) // Regster custom handler for specific http errors. app.OnErrorCode(siris.StatusInternalServerError, func(ctx context.Context) { // .Values are used to communicate between handlers, middleware. errMessage := ctx.Values().GetString("error") if errMessage != "" { ctx.Writef("Internal server error: %s", errMessage) return } ctx.Writef("(Unexpected) internal server error") }) app.Use(func(ctx context.Context) { ctx.Application().Logger().Infof("Begin request for path: %s", ctx.Path()) ctx.Next() }) // app.Done(func(ctx context.Context) {}) // Method POST: http://localhost:8080/decode app.Post("/decode", func(ctx context.Context) { var user User ctx.ReadJSON(&user) ctx.Writef("%s %s is %d years old and comes from %s", user.Firstname, user.Lastname, user.Age, user.City) }) // Method GET: http://localhost:8080/encode app.Get("/encode", func(ctx context.Context) { doe := User{ Username: "Johndoe", Firstname: "John", Lastname: "Doe", City: "Neither FBI knows!!!", Age: 25, } ctx.JSON(doe) }) // Method GET: http://localhost:8080/profile/anytypeofstring app.Get("/profile/{username:string}", profileByUsername) usersRoutes := app.Party("/users", logThisMiddleware) { // Method GET: http://localhost:8080/users/42 usersRoutes.Get("/{id:int min(1)}", getUserByID) // Method POST: http://localhost:8080/users/create usersRoutes.Post("/create", createUser) } // Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080. app.Run(siris.Addr(":8080"), siris.WithCharset("UTF-8")) } func logThisMiddleware(ctx context.Context) { ctx.Application().Logger().Infof("Path: %s | IP: %s", ctx.Path(), ctx.RemoteAddr()) // .Next is required to move forward to the chain of handlers, // if missing then it stops the execution at this handler. ctx.Next() } func profileByUsername(ctx context.Context) { // .Params are used to get dynamic path parameters. username := ctx.Params().Get("username") ctx.ViewData("Username", username) // renders "./views/users/profile.html" // with {{ .Username }} equals to the username dynamic path parameter. ctx.View("users/profile.html") } func getUserByID(ctx context.Context) { userID := ctx.Params().Get("id") // Or convert directly using: .Values().GetInt/GetInt64 etc... // your own db fetch here instead of user :=... user := User{Username: "username" + userID} ctx.XML(user) } func createUser(ctx context.Context) { var user User err := ctx.ReadForm(&user) if err != nil { ctx.Values().Set("error", "creating user, read and parse form failed. "+err.Error()) ctx.StatusCode(siris.StatusInternalServerError) return } // renders "./views/users/create_verification.html" // with {{ . }} equals to the User object, i.e {{ .Username }} , {{ .Firstname}} etc... ctx.ViewData("", user) ctx.View("users/create_verification.html") }
Hosts ¶
Access to all hosts that serve your application can be provided by the `Application#Hosts` field, after the `Run` method.
But the most common scenario is that you may need access to the host before the `Run` method, there are two ways of gain access to the host supervisor, read below.
First way is to use the `app.NewHost` to create a new host and use one of its `Serve` or `Listen` functions to start the application via the `siris#Raw` Runner. Note that this way needs an extra import of the `net/http` package.
Example Code:
h := app.NewHost(&http.Server{Addr:":8080"}) h.RegisterOnShutdown(func(){ println("server was closed!") }) app.Run(siris.Raw(h.ListenAndServe))
Second, and probably easier way is to use the `host.Configurator`.
Note that this method requires an extra import statement of "github.com/go-siris/siris/core/host" when using go < 1.9, if you're targeting on go1.9 then you can use the `siris#Supervisor` and omit the extra host import.
All common `Runners` we saw earlier (`siris#Addr, siris#Listener, siris#Server, siris#TLS, siris#AutoTLS`) accept a variadic argument of `host.Configurator`, there are just `func(*host.Supervisor)`. Therefore the `Application` gives you the rights to modify the auto-created host supervisor through these.
Example Code:
package main import ( stdContext "context" "time" "github.com/go-siris/siris" "github.com/go-siris/siris/context" "github.com/go-siris/siris/core/host" ) func main() { app := siris.New() app.Get("/", func(ctx context.Context) { ctx.HTML("<h1>Hello, try to refresh the page after ~10 secs</h1>") }) app.Logger().Info("Wait 10 seconds and check your terminal again") // simulate a shutdown action here... go func() { <-time.After(10 * time.Second) timeout := 5 * time.Second ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout) defer cancel() // close all hosts, this will notify the callback we had register // inside the `configureHost` func. app.Shutdown(ctx) }() // start the server as usual, the only difference is that // we're adding a second (optional) function // to configure the just-created host supervisor. // // http://localhost:8080 // wait 10 seconds and check your terminal. app.Run(siris.Addr(":8080", configureHost), siris.WithoutServerError(siris.ErrServerClosed)) } func configureHost(su *host.Supervisor) { // here we have full access to the host that will be created // inside the `Run` function. // // we register a shutdown "event" callback su.RegisterOnShutdown(func() { println("server is closed") }) // su.RegisterOnError // su.RegisterOnServe }
Routing ¶
All HTTP methods are supported, developers can also register handlers for same paths for different methods. The first parameter is the HTTP Method, second parameter is the request path of the route, third variadic parameter should contains one or more context.Handler executed by the registered order when a user requests for that specific resouce path from the server.
Example code:
app := siris.New() app.Handle("GET", "/contact", func(ctx context.Context){ ctx.HTML("<h1> Hello from /contact </h1>") })
In order to make things easier for the user, Siris provides functions for all HTTP Methods. The first parameter is the request path of the route, second variadic parameter should contains one or more context.Handler executed by the registered order when a user requests for that specific resouce path from the server.
Example code:
app := siris.New() // Method: "GET" app.Get("/", handler) // Method: "POST" app.Post("/", handler) // Method: "PUT" app.Put("/", handler) // Method: "DELETE" app.Delete("/", handler) // Method: "OPTIONS" app.Options("/", handler) // Method: "TRACE" app.Trace("/", handler) // Method: "CONNECT" app.Connect("/", handler) // Method: "HEAD" app.Head("/", handler) // Method: "PATCH" app.Patch("/", handler) // register the route for all HTTP Methods app.Any("/", handler) func handler(ctx context.Context){ ctx.Writef("Hello from method: %s and path: %s", ctx.Method(), ctx.Path()) }
Grouping Routes ¶
A set of routes that are being groupped by path prefix can (optionally) share the same middleware handlers and template layout. A group can have a nested group too.
`.Party` is being used to group routes, developers can declare an unlimited number of (nested) groups.
Example code:
users:= app.Party("/users", myAuthHandler) // http://myhost.com/users/42/profile users.Get("/{userid:int}/profile", userProfileHandler) // http://myhost.com/users/messages/1 users.Get("/inbox/{messageid:int}", userMessageHandler) app.Run(siris.Addr("myhost.com:80"))
Custom HTTP Errors ¶
Siris developers are able to register their own handlers for http statuses like 404 not found, 500 internal server error and so on.
Example code:
// when 404 then render the template $templatedir/errors/404.html app.OnErrorCode(siris.StatusNotFound, func(ctx context.Context){ ctx.View("errors/404.html") }) app.OnErrorCode(500, func(ctx context.Context){ // ... })
Basic HTTP API ¶
With the help of Siris's expressionist router you can build any form of API you desire, with safety.
Example code:
package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) func main() { app := siris.New() // registers a custom handler for 404 not found http (error) status code, // fires when route not found or manually by ctx.StatusCode(siris.StatusNotFound). app.OnErrorCode(siris.StatusNotFound, notFoundHandler) // GET -> HTTP Method // / -> Path // func(ctx context.Context) -> The route's handler. // // Third receiver should contains the route's handler(s), they are executed by order. app.Handle("GET", "/", func(ctx context.Context) { // navigate to the middle of $GOPATH/src/github.com/go-siris/siris/context/context.go // to overview all context's method (there a lot of them, read that and you will learn how siris works too) ctx.HTML("Hello from " + ctx.Path()) // Hello from / }) app.Get("/home", func(ctx context.Context) { ctx.Writef(`Same as app.Handle("GET", "/", [...])`) }) app.Get("/donate", donateHandler, donateFinishHandler) // Pssst, don't forget dynamic-path example for more "magic"! app.Get("/api/users/{userid:int min(1)}", func(ctx context.Context) { userID, err := ctx.Params().GetInt("userid") if err != nil { ctx.Writef("error while trying to parse userid parameter," + "this will never happen if :int is being used because if it's not integer it will fire Not Found automatically.") ctx.StatusCode(siris.StatusBadRequest) return } ctx.JSON(map[string]interface{}{ // you can pass any custom structured go value of course. "user_id": userID, }) }) // app.Post("/", func(ctx context.Context){}) -> for POST http method. // app.Put("/", func(ctx context.Context){})-> for "PUT" http method. // app.Delete("/", func(ctx context.Context){})-> for "DELETE" http method. // app.Options("/", func(ctx context.Context){})-> for "OPTIONS" http method. // app.Trace("/", func(ctx context.Context){})-> for "TRACE" http method. // app.Head("/", func(ctx context.Context){})-> for "HEAD" http method. // app.Connect("/", func(ctx context.Context){})-> for "CONNECT" http method. // app.Patch("/", func(ctx context.Context){})-> for "PATCH" http method. // app.Any("/", func(ctx context.Context){}) for all http methods. // More than one route can contain the same path with a different http mapped method. // You can catch any route creation errors with: // route, err := app.Get(...) // set a name to a route: route.Name = "myroute" // You can also group routes by path prefix, sharing middleware(s) and done handlers. adminRoutes := app.Party("/admin", adminMiddleware) adminRoutes.Done(func(ctx context.Context) { // executes always last if ctx.Next() ctx.Application().Logger().Info("response sent to " + ctx.Path()) }) // adminRoutes.Layout("/views/layouts/admin.html") // set a view layout for these routes, see more at intermediate/view examples. // GET: http://localhost:8080/admin adminRoutes.Get("/", func(ctx context.Context) { // [...] ctx.StatusCode(siris.StatusOK) // default is 200 == siris.StatusOK ctx.HTML("<h1>Hello from admin/</h1>") ctx.Next() // in order to execute the party's "Done" Handler(s) }) // GET: http://localhost:8080/admin/login adminRoutes.Get("/login", func(ctx context.Context) { // [...] }) // POST: http://localhost:8080/admin/login adminRoutes.Post("/login", func(ctx context.Context) { // [...] }) // subdomains, easier than ever, should add localhost or 127.0.0.1 into your hosts file, // etc/hosts on unix or C:/windows/system32/drivers/etc/hosts on windows. v1 := app.Party("v1.") { // braces are optional, it's just type of style, to group the routes visually. // http://v1.localhost:8080 v1.Get("/", func(ctx context.Context) { ctx.HTML("Version 1 API. go to <a href='" + ctx.Path() + "/api" + "'>/api/users</a>") }) usersAPI := v1.Party("/api/users") { // http://v1.localhost:8080/api/users usersAPI.Get("/", func(ctx context.Context) { ctx.Writef("All users") }) // http://v1.localhost:8080/api/users/42 usersAPI.Get("/{userid:int}", func(ctx context.Context) { ctx.Writef("user with id: %s", ctx.Params().Get("userid")) }) } } // wildcard subdomains. wildcardSubdomain := app.Party("*.") { wildcardSubdomain.Get("/", func(ctx context.Context) { ctx.Writef("Subdomain can be anything, now you're here from: %s", ctx.Subdomain()) }) } // http://localhost:8080 // http://localhost:8080/home // http://localhost:8080/donate // http://localhost:8080/api/users/42 // http://localhost:8080/admin // http://localhost:8080/admin/login // // http://localhost:8080/api/users/0 // http://localhost:8080/api/users/blabla // http://localhost:8080/wontfound // // if hosts edited: // http://v1.localhost:8080 // http://v1.localhost:8080/api/users // http://v1.localhost:8080/api/users/42 // http://anything.localhost:8080 app.Run(siris.Addr(":8080")) } func adminMiddleware(ctx context.Context) { // [...] ctx.Next() // to move to the next handler, or don't that if you have any auth logic. } func donateHandler(ctx context.Context) { ctx.Writef("Just like an inline handler, but it can be " + "used by other package, anywhere in your project.") // let's pass a value to the next handler // Values is the way handlers(or middleware) are communicating between each other. ctx.Values().Set("donate_url", "https://github.com/go-siris/siris#buy-me-a-cup-of-coffee") ctx.Next() // in order to execute the next handler in the chain, look donate route. } func donateFinishHandler(ctx context.Context) { // values can be any type of object so we could cast the value to a string // but Siris provides an easy to do that, if donate_url is not defined, then it returns an empty string instead. donateURL := ctx.Values().GetString("donate_url") ctx.Application().Logger().Info("donate_url value was: " + donateURL) ctx.Writef("\n\nDonate sent(?).") } func notFoundHandler(ctx context.Context) { ctx.HTML("Custom route for 404 not found http code, here you can render a view, html, json <b>any valid response</b>.") }
Parameterized Path ¶
At the previous example, we've seen static routes, group of routes, subdomains, wildcard subdomains, a small example of parameterized path with a single known paramete and custom http errors, now it's time to see wildcard parameters and macros.
Siris, like net/http std package registers route's handlers by a Handler, the Siris' type of handler is just a func(ctx context.Context) where context comes from github.com/go-siris/siris/context. Until go 1.9 you will have to import that package too, after go 1.9 this will be not be necessary.
Siris has the easiest and the most powerful routing process you have ever meet.
At the same time, Siris has its own interpeter(yes like a programming language) for route's path syntax and their dynamic path parameters parsing and evaluation, I am calling them "macros" for shortcut. How? It calculates its needs and if not any special regexp needed then it just registers the route with the low-level path syntax, otherwise it pre-compiles the regexp and adds the necessary middleware(s).
Standard macro types for parameters:
+------------------------+ | {param:string} | +------------------------+ string type anything +------------------------+ | {param:int} | +------------------------+ int type only numbers (0-9) +------------------------+ | {param:alphabetical} | +------------------------+ alphabetical/letter type letters only (upper or lowercase) +------------------------+ | {param:file} | +------------------------+ file type letters (upper or lowercase) numbers (0-9) underscore (_) dash (-) point (.) no spaces ! or other character +------------------------+ | {param:path} | +------------------------+ path type anything, should be the last part, more than one path segment, i.e: /path1/path2/path3 , ctx.Params().GetString("param") == "/path1/path2/path3"
if type is missing then parameter's type is defaulted to string, so {param} == {param:string}.
If a function not found on that type then the "string"'s types functions are being used. i.e:
{param:int min(3)}
Besides the fact that Siris provides the basic types and some default "macro funcs" you are able to register your own too!.
Register a named path parameter function:
app.Macros().Int.RegisterFunc("min", func(argument int) func(paramValue string) bool { [...] return true/false -> true means valid. })
at the func(argument ...) you can have any standard type, it will be validated before the server starts so don't care about performance here, the only thing it runs at serve time is the returning func(paramValue string) bool.
{param:string equal(siris)} , "siris" will be the argument here: app.Macros().String.RegisterFunc("equal", func(argument string) func(paramValue string) bool { return func(paramValue string){ return argument == paramValue } })
Example code:
// you can use the "string" type which is valid for a single path parameter that can be anything. app.Get("/username/{name}", func(ctx context.Context) { ctx.Writef("Hello %s", ctx.Params().Get("name")) }) // type is missing = {name:string} // Let's register our first macro attached to int macro type. // "min" = the function // "minValue" = the argument of the function // func(string) bool = the macro's path parameter evaluator, this executes in serve time when // a user requests a path which contains the :int macro type with the min(...) macro parameter function. app.Macros().Int.RegisterFunc("min", func(minValue int) func(string) bool { // do anything before serve here [...] // at this case we don't need to do anything return func(paramValue string) bool { n, err := strconv.Atoi(paramValue) if err != nil { return false } return n >= minValue } }) // http://localhost:8080/profile/id>=1 // this will throw 404 even if it's found as route on : /profile/0, /profile/blabla, /profile/-1 // macro parameter functions are optional of course. app.Get("/profile/{id:int min(1)}", func(ctx context.Context) { // second parameter is the error but it will always nil because we use macros, // the validaton already happened. id, _ := ctx.Params().GetInt("id") ctx.Writef("Hello id: %d", id) }) // to change the error code per route's macro evaluator: app.Get("/profile/{id:int min(1)}/friends/{friendid:int min(1) else 504}", func(ctx context.Context) { id, _ := ctx.Params().GetInt("id") friendid, _ := ctx.Params().GetInt("friendid") ctx.Writef("Hello id: %d looking for friend id: ", id, friendid) }) // this will throw e 504 error code instead of 404 if all route's macros not passed. // http://localhost:8080/game/a-zA-Z/level/0-9 // remember, alphabetical is lowercase or uppercase letters only. app.Get("/game/{name:alphabetical}/level/{level:int}", func(ctx context.Context) { ctx.Writef("name: %s | level: %s", ctx.Params().Get("name"), ctx.Params().Get("level")) }) // let's use a trivial custom regexp that validates a single path parameter // which its value is only lowercase letters. // http://localhost:8080/lowercase/kataras app.Get("/lowercase/{name:string regexp(^[a-z]+)}", func(ctx context.Context) { ctx.Writef("name should be only lowercase, otherwise this handler will never executed: %s", ctx.Params().Get("name")) }) // http://localhost:8080/single_file/app.js app.Get("/single_file/{myfile:file}", func(ctx context.Context) { ctx.Writef("file type validates if the parameter value has a form of a file name, got: %s", ctx.Params().Get("myfile")) }) // http://localhost:8080/myfiles/any/directory/here/ // this is the only macro type that accepts any number of path segments. app.Get("/myfiles/{directory:path}", func(ctx context.Context) { ctx.Writef("path type accepts any number of path segments, path after /myfiles/ is: %s", ctx.Params().Get("directory")) }) // for wildcard path (any number of path segments) without validation you can use: // /myfiles/*directory // "{param}"'s performance is exactly the same of ":param"'s. // alternatives -> ":param" for single path parameter and "*paramPath" for wildcard path parameter // acquire them by ctx.Params().Get as always. if err := app.Run(siris.Addr(":8080")); err != nil { panic(err) } }
A path parameter name should contain only alphabetical letters, symbols, containing '_' and numbers are NOT allowed. If route failed to be registered, the app will panic without any warnings if you didn't catch the second return value(error) on .Handle/.Get....
Last, do not confuse ctx.Values() with ctx.Params(). Path parameter's values goes to ctx.Params() and context's local storage that can be used to communicate between handlers and middleware(s) goes to ctx.Values(), path parameters and the rest of any custom values are separated for your own good.
Run
$ go run main.go
Static Files
// StaticServe serves a directory as web resource // it's the simpliest form of the Static* functions // Almost same usage as StaticWeb // accepts only one required parameter which is the systemPath, // the same path will be used to register the GET and HEAD method routes. // If second parameter is empty, otherwise the requestPath is the second parameter // it uses gzip compression (compression on each request, no file cache). // // Returns the GET *Route. StaticServe(systemPath string, requestPath ...string) (*Route, error) // StaticContent registers a GET and HEAD method routes to the requestPath // that are ready to serve raw static bytes, memory cached. // // Returns the GET *Route. StaticContent(reqPath string, cType string, content []byte) (*Route, error) // StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly // First parameter is the request path, the path which the files in the vdir will be served to, for example "/static" // Second parameter is the (virtual) directory path, for example "./assets" // Third parameter is the Asset function // Forth parameter is the AssetNames function. // // Returns the GET *Route. // // Example: https://github.com/go-siris/siris/tree/master/_examples/intermediate/serve-embedded-files StaticEmbedded(requestPath string, vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string) (*Route, error) // Favicon serves static favicon // accepts 2 parameters, second is optional // favPath (string), declare the system directory path of the __.ico // requestPath (string), it's the route's path, by default this is the "/favicon.ico" because some browsers tries to get this by default first, // you can declare your own path if you have more than one favicon (desktop, mobile and so on) // // this func will add a route for you which will static serve the /yuorpath/yourfile.ico to the /yourfile.ico // (nothing special that you can't handle by yourself). // Note that you have to call it on every favicon you have to serve automatically (desktop, mobile and so on). // // Returns the GET *Route. Favicon(favPath string, requestPath ...string) (*Route, error) // StaticWeb returns a handler that serves HTTP requests // with the contents of the file system rooted at directory. // // first parameter: the route path // second parameter: the system directory // third OPTIONAL parameter: the exception routes // (= give priority to these routes instead of the static handler) // for more options look app.StaticHandler. // // app.StaticWeb("/static", "./static") // // As a special case, the returned file server redirects any request // ending in "/index.html" to the same path, without the final // "index.html". // // StaticWeb calls the StaticHandler(systemPath, listingDirectories: false, gzip: false ). // // Returns the GET *Route. StaticWeb(requestPath string, systemPath string, exceptRoutes ...*Route) (*Route, error)
Example code:
package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) func main() { app := siris.New() // This will serve the ./static/favicons/iris_32_32.ico to: localhost:8080/favicon.ico app.Favicon("./static/favicons/iris_32_32.ico") // app.Favicon("./static/favicons/iris_32_32.ico", "/favicon_48_48.ico") // This will serve the ./static/favicons/iris_32_32.ico to: localhost:8080/favicon_48_48.ico app.Get("/", func(ctx context.Context) { ctx.HTML(`<a href="/favicon.ico"> press here to see the favicon.ico</a>. At some browsers like chrome, it should be visible at the top-left side of the browser's window, because some browsers make requests to the /favicon.ico automatically, so Siris serves your favicon in that path too (you can change it).`) }) // if favicon doesn't show to you, try to clear your browser's cache. app.Run(siris.Addr(":8080")) }
More examples can be found here: https://github.com/go-siris/siris/tree/master/_examples/beginner/file-server
Middleware Ecosystem ¶
Middleware is just a concept of ordered chain of handlers. Middleware can be registered globally, per-party, per-subdomain and per-route.
Example code:
// globally // before any routes, appends the middleware to all routes app.Use(func(ctx context.Context){ // ... any code here ctx.Next() // in order to continue to the next handler, // if that is missing then the next in chain handlers will be not executed, // useful for authentication middleware }) // globally // after or before any routes, prepends the middleware to all routes app.UseGlobal(handler1, handler2, handler3) // per-route app.Post("/login", authenticationHandler, loginPageHandler) // per-party(group of routes) users := app.Party("/users", usersMiddleware) users.Get("/", usersIndex) // per-subdomain mysubdomain := app.Party("mysubdomain.", firstMiddleware) mysubdomain.Use(secondMiddleware) mysubdomain.Get("/", mysubdomainIndex) // per wildcard, dynamic subdomain dynamicSub := app.Party(".*", firstMiddleware, secondMiddleware) dynamicSub.Get("/", func(ctx context.Context){ ctx.Writef("Hello from subdomain: "+ ctx.Subdomain()) })
Siris is able to wrap and convert any external, third-party Handler you used to use to your web application. Let's convert the https://github.com/rs/cors net/http external middleware which returns a `next form` handler.
Example code:
package main import ( "github.com/rs/cors" "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) func main() { app := siris.New() corsOptions := cors.Options{ AllowedOrigins: []string{"*"}, AllowCredentials: true, } corsWrapper := cors.New(corsOptions).ServeHTTP app.WrapRouter(corsWrapper) v1 := app.Party("/api/v1") { v1.Get("/", h) v1.Put("/put", h) v1.Post("/post", h) } app.Run(siris.Addr(":8080")) } func h(ctx context.Context) { ctx.Application().Logger().Info(ctx.Path()) ctx.Writef("Hello from %s", ctx.Path()) }
View Engine ¶
Siris supports 5 template engines out-of-the-box, developers can still use any external golang template engine, as `context.ResponseWriter()` is an `io.Writer`.
All of these five template engines have common features with common API, like Layout, Template Funcs, Party-specific layout, partial rendering and more.
The standard html, its template parser is the golang.org/pkg/html/template/. Django, its template parser is the github.com/flosch/pongo2 Pug(Jade), its template parser is the github.com/Joker/jade Handlebars, its template parser is the github.com/aymerick/raymond Amber, its template parser is the github.com/eknkc/amber
Example code:
package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) func main() { app := siris.New() // defaults to these // - standard html | app.HTML(...) // - django | app.Django(...) // - pug(jade) | app.Pug(...) // - handlebars | app.Handlebars(...) // - amber | app.Amber(...) tmpl := app.HTML("./templates", ".html") tmpl.Reload(true) // reload templates on each request (development mode) // default template funcs are: // // - {{ urlpath "mynamedroute" "pathParameter_ifneeded" }} // - {{ render "header.html" }} // - {{ render_r "header.html" }} // partial relative path to current page // - {{ yield }} // - {{ current }} tmpl.AddFunc("greet", func(s string) string { return "Greetings " + s + "!" }) app.AttachView(tmpl) app.Get("/", hi) // http://localhost:8080 app.Run(siris.Addr(":8080"), siris.WithCharset("UTF-8")) // defaults to that but you can change it. } func hi(ctx context.Context) { ctx.ViewData("Title", "Hi Page") ctx.ViewData("Name", "Siris") // {{.Name}} will render: Siris // ctx.ViewData("", myCcustomStruct{}) ctx.View("hi.html") }
View engine supports bundled(https://github.com/jteeuwen/go-bindata) template files too. go-bindata gives you two functions, asset and assetNames, these can be set to each of the template engines using the `.Binary` func.
Example code:
package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" ) func main() { app := siris.New() // $ go get -u github.com/jteeuwen/go-bindata/... // $ go-bindata ./templates/... // $ go build // $ ./embedding-templates-into-app // html files are not used, you can delete the folder and run the example app.AttachView(app.HTML("./templates", ".html").Binary(Asset, AssetNames)) app.Get("/", hi) // http://localhost:8080 app.Run(siris.Addr(":8080")) } type page struct { Title, Name string } func hi(ctx context.Context) { ctx.ViewData("", page{Title: "Hi Page", Name: "siris"}) ctx.View("hi.html") }
A real example can be found here: https://github.com/go-siris/siris/tree/master/_examples/intermediate/view/embedding-templates-into-app.
Enable auto-reloading of templates on each request. Useful while developers are in dev mode as they no neeed to restart their app on every template edit.
Example code:
pugEngine := app.Pug("./templates", ".jade") pugEngine.Reload(true) // <--- set to true to re-build the templates on each request. app.AttachView(pugEngine)
Each one of these template engines has different options located here: https://github.com/go-siris/siris/tree/master/view .
Sessions ¶
This example will show how to store and access data from a session.
You don’t need any third-party library, but If you want you can use any session manager compatible or not.
In this example we will only allow authenticated users to view our secret message on the /secret page. To get access to it, the will first have to visit /login to get a valid session cookie, which logs him in. Additionally he can visit /logout to revoke his access to our secret message.
Example code:
// sessions.go package main import ( "github.com/go-siris/siris" "github.com/go-siris/siris/context" "github.com/go-siris/siris/sessions" ) var ( key = "my_sessionid" ) func secret(ctx context.Context) { // Check if user is authenticated if auth, _ := ctx.Session().Get("authenticated"); !auth { ctx.StatusCode(siris.StatusForbidden) return } // Print secret message ctx.Writef("The cake is a lie!") } func login(ctx context.Context) { session := ctx.Session() // Authentication goes here // ... // Set user as authenticated session.Set("authenticated", true) } func logout(ctx context.Context) { session := ctx.Session() // Revoke users authentication session.Set("authenticated", false) } func main() { app := siris.New() app.AttachSessionManager("memory", &sessions.ManagerConfig{ CookieName: "go-session-id", EnableSetCookie: true, Gclifetime: 3600, Maxlifetime: 7200, }) app.Get("/secret", secret) app.Get("/login", login) app.Get("/logout", logout) app.Run(siris.Addr(":8080")) }
Running the example:
$ go run sessions.go $ curl -s http://localhost:8080/secret Forbidden $ curl -s -I http://localhost:8080/login Set-Cookie: mysessionid=MTQ4NzE5Mz... $ curl -s --cookie "mysessionid=MTQ4NzE5Mz..." http://localhost:8080/secret The cake is a lie!
That's the basics ¶
But you should have a basic idea of the framework by now, we just scratched the surface. If you enjoy what you just saw and want to learn more, please follow the below links:
Examples:
https://github.com/go-siris/siris/tree/master/_examples
Built'n Middleware:
https://github.com/go-siris/siris/tree/master/middleware
Community Middleware:
https://github.com/iris-contrib/middleware
Home Page:
http://go-siris.com
Index ¶
- Constants
- Variables
- func ToHandler(handler interface{}) context.Handler
- type Application
- func (app *Application) AttachSessionManager(provider string, cfg *sessions.ManagerConfig)
- func (app *Application) AttachView(viewEngine view.Engine) error
- func (app *Application) Build() (err error)
- func (app *Application) ConfigurationReadOnly() context.ConfigurationReadOnly
- func (app *Application) Configure(configurators ...Configurator) *Application
- func (app *Application) ConfigureHost(configurators ...host.Configurator) *Application
- func (app *Application) Listen(addr string)
- func (app *Application) ListenLETSENCRYPT(addr string, cacheDirOptional ...string)
- func (app *Application) ListenTLS(addr string, certFile, keyFile string)
- func (app *Application) ListenUNIX(socketFile string, mode os.FileMode)
- func (app *Application) Logger() *zap.SugaredLogger
- func (app *Application) NewHost(srv *http.Server) *host.Supervisor
- func (app *Application) OnStatusCode(statusCode int, handler context.Handler)
- func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error
- func (app *Application) SPA(assetHandler context.Handler)
- func (app *Application) Serve(l net.Listener) error
- func (app *Application) SessionManager() (*sessions.Manager, error)
- func (app *Application) Shutdown(ctx stdContext.Context) error
- func (app *Application) View(writer io.Writer, filename string, layout string, bindingData interface{}) error
- type Configurator
- func WithCharset(charset string) Configurator
- func WithConfiguration(c configuration.Configuration) Configurator
- func WithOtherValue(key string, val interface{}) Configurator
- func WithRemoteAddrHeader(headerName string) Configurator
- func WithTimeFormat(timeformat string) Configurator
- func WithoutRemoteAddrHeader(headerName string) Configurator
- type Context
- type Handler
- type Map
- type Party
- type Runner
- func Addr(addr string, hostConfigs ...host.Configurator) Runner
- func AutoTLS(addr string, hostConfigs ...host.Configurator) Runner
- func Listener(l net.Listener, hostConfigs ...host.Configurator) Runner
- func Raw(f func() error) Runner
- func Server(srv *http.Server, hostConfigs ...host.Configurator) Runner
- func TLS(addr string, certFile, keyFile string, hostConfigs ...host.Configurator) Runner
- type Supervisor
Constants ¶
const ( // MethodNone is a Virtual method // to store the "offline" routes. // // Conversion for router.MethodNone. MethodNone = router.MethodNone // NoLayout to disable layout for a particular template file // Conversion for view.NoLayout. NoLayout = view.NoLayout )
const ( // DebugLevel logs are typically voluminous, and are usually disabled in // production. DebugLevel = zap.DebugLevel // InfoLevel is the default logging priority. InfoLevel = zap.InfoLevel // WarnLevel logs are more important than Info, but don't need individual // human review. WarnLevel = zap.WarnLevel // ErrorLevel logs are high-priority. If an application is running smoothly, // it shouldn't generate any error-level logs. ErrorLevel = zap.ErrorLevel // DPanicLevel logs are particularly important errors. In development the // logger panics after writing the message. DPanicLevel = zap.DPanicLevel // PanicLevel logs a message, then panics. PanicLevel = zap.PanicLevel // FatalLevel logs a message, then calls os.Exit(1). FatalLevel = zap.FatalLevel )
These are the different logging levels. You can set the logging level to log on the application 's instance of logger, obtained with `app.Logger()`.
These are conversions from logrus.
const ( StatusContinue = 100 // RFC 7231, 6.2.1 StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 StatusProcessing = 102 // RFC 2518, 10.1 StatusOK = 200 // RFC 7231, 6.3.1 StatusCreated = 201 // RFC 7231, 6.3.2 StatusAccepted = 202 // RFC 7231, 6.3.3 StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 StatusNoContent = 204 // RFC 7231, 6.3.5 StatusResetContent = 205 // RFC 7231, 6.3.6 StatusPartialContent = 206 // RFC 7233, 4.1 StatusMultiStatus = 207 // RFC 4918, 11.1 StatusAlreadyReported = 208 // RFC 5842, 7.1 StatusIMUsed = 226 // RFC 3229, 10.4.1 StatusMultipleChoices = 300 // RFC 7231, 6.4.1 StatusMovedPermanently = 301 // RFC 7231, 6.4.2 StatusFound = 302 // RFC 7231, 6.4.3 StatusSeeOther = 303 // RFC 7231, 6.4.4 StatusNotModified = 304 // RFC 7232, 4.1 StatusUseProxy = 305 // RFC 7231, 6.4.5 StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 StatusPermanentRedirect = 308 // RFC 7538, 3 StatusBadRequest = 400 // RFC 7231, 6.5.1 StatusPaymentRequired = 402 // RFC 7231, 6.5.2 StatusForbidden = 403 // RFC 7231, 6.5.3 StatusNotFound = 404 // RFC 7231, 6.5.4 StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 StatusNotAcceptable = 406 // RFC 7231, 6.5.6 StatusProxyAuthRequired = 407 // RFC 7235, 3.2 StatusRequestTimeout = 408 // RFC 7231, 6.5.7 StatusConflict = 409 // RFC 7231, 6.5.8 StatusGone = 410 // RFC 7231, 6.5.9 StatusLengthRequired = 411 // RFC 7231, 6.5.10 StatusPreconditionFailed = 412 // RFC 7232, 4.2 StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 StatusExpectationFailed = 417 // RFC 7231, 6.5.14 StatusTeapot = 418 // RFC 7168, 2.3.3 StatusUnprocessableEntity = 422 // RFC 4918, 11.2 StatusLocked = 423 // RFC 4918, 11.3 StatusFailedDependency = 424 // RFC 4918, 11.4 StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 StatusPreconditionRequired = 428 // RFC 6585, 3 StatusTooManyRequests = 429 // RFC 6585, 4 StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 StatusInternalServerError = 500 // RFC 7231, 6.6.1 StatusNotImplemented = 501 // RFC 7231, 6.6.2 StatusBadGateway = 502 // RFC 7231, 6.6.3 StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 StatusInsufficientStorage = 507 // RFC 4918, 11.5 StatusLoopDetected = 508 // RFC 5842, 7.2 StatusNotExtended = 510 // RFC 2774, 7 StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 )
HTTP status codes as registered with IANA. See: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Raw Copy from the net/http std package in order to recude the import path of "net/http" for the users.
These may or may not stay.
const ( MethodGet = "GET" MethodPost = "POST" MethodPut = "PUT" MethodDelete = "DELETE" MethodConnect = "CONNECT" MethodHead = "HEAD" MethodPatch = "PATCH" MethodOptions = "OPTIONS" MethodTrace = "TRACE" )
These may or may not stay, you can use net/http's constants too.
const ( // Version is the current version number of the Siris Web framework. // // Look https://github.com/go-siris/siris#where-can-i-find-older-versions for older versions. Version = "7.4.0" )
Variables ¶
var ( // HTML view engine. // Conversion for the view.HTML. HTML = view.HTML // Django view engine. // Conversion for the view.Django. Django = view.Django // Handlebars view engine. // Conversion for the view.Handlebars. Handlebars = view.Handlebars // Pug view engine. // Conversion for the view.Pug. Pug = view.Pug // Amber view engine. // Conversion for the view.Amber. Amber = view.Amber )
var Cache = cache.Handler
Cache provides cache capabilities to a route's handler. Usage:
Get("/", siris.Cache(time.Duration(10*time.Second)), func(ctx context.Context){ ctx.Writef("Hello, world!") // or a template or anything else })
Deprecated. Use "github.com/go-siris/siris/cache" sub-package which contains the full features instead.
var CheckErr = func(err error) { if err != nil { panic(err) } }
CheckErr is the old `Must`. It panics on errors as expected with the old listen functions, change of this method will affect only ListenXXX functions.
Its only callers are the following, deprecated, listen functions.
var EnableQUICSupport = func(app *Application) { app.config.EnableQUICSupport = true }
EnableQUICSupport turns on the Reuseport feature.
var EnableReuseport = func(app *Application) { app.config.EnableReuseport = true }
EnableReuseport turns on the Reuseport feature.
var ErrServerClosed = http.ErrServerClosed
ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe, and ListenAndServeTLS methods after a call to Shutdown or Close.
Conversion for the http.ErrServerClosed.
var ( // LimitRequestBodySize is a middleware which sets a request body size limit // for all next handlers in the chain. LimitRequestBodySize = context.LimitRequestBodySize )
var RegisterOnInterruptHook = host.RegisterOnInterruptHook
RegisterOnInterruptHook registers a global function to call when CTRL+C/CMD+C pressed or a unix kill command received.
A shortcut for the `host#RegisterOnInterrupt`.
var TOML = configuration.TOML
TOML load the TOML Configuration
var WithFireMethodNotAllowed = func(app *Application) { app.config.FireMethodNotAllowed = true }
WithFireMethodNotAllowed enanbles the FireMethodNotAllowed setting.
See `Configuration`.
var WithJSONInteratorReplacement = func(app *Application) { app.config.JSONInteratorReplacement = true }
WithJSONInteratorReplacement enables JSONInteratorReplacement setting.
See `Configuration`.
var WithPathEscape = func(app *Application) { app.config.EnablePathEscape = true }
WithPathEscape enanbles the PathEscape setting.
See `Configuration`.
var WithoutAutoFireStatusCode = func(app *Application) { app.config.DisableAutoFireStatusCode = true }
WithoutAutoFireStatusCode disables the AutoFireStatusCode setting.
See `Configuration`.
var WithoutBanner = func(app *Application) { app.config.DisableBanner = true }
WithoutBanner turns off the write banner on server startup.
var WithoutBodyConsumptionOnUnmarshal = func(app *Application) { app.config.DisableBodyConsumptionOnUnmarshal = true }
WithoutBodyConsumptionOnUnmarshal disables BodyConsumptionOnUnmarshal setting.
See `Configuration`.
var WithoutInterruptHandler = func(app *Application) { app.config.DisableInterruptHandler = true }
WithoutInterruptHandler disables the automatic graceful server shutdown when control/cmd+C pressed.
var WithoutPathCorrection = func(app *Application) { app.config.DisablePathCorrection = true }
WithoutPathCorrection disables the PathCorrection setting.
See `Configuration`.
var YAML = configuration.YAML
YAML load the YAML Configuration
Functions ¶
func ToHandler ¶
ToHandler converts native http.Handler & http.HandlerFunc to context.Handler.
Supported form types:
.ToHandler(h http.Handler) .ToHandler(func(w http.ResponseWriter, r *http.Request)) .ToHandler(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc))
Deprecated. Use the "core/handlerconv" package instead, equivalent to `ToHandler` is its `FromStd` function.
Types ¶
type Application ¶
type Application struct { // routing embedded | exposing APIBuilder's and Router's public API. *router.APIBuilder *router.Router ContextPool *context.Pool // Hosts contains a list of all servers (Host Supervisors) that this app is running on. // // Hosts may be empty only if application ran(`app.Run`) with `siris.Raw` option runner, // otherwise it contains a single host (`app.Hosts[0]`). // // Additional Host Supervisors can be added to that list by calling the `app.NewHost` manually. // // Hosts field is available after `Run` or `NewHost`. Hosts []*host.Supervisor // contains filtered or unexported fields }
Application is responsible to manage the state of the application. It contains and handles all the necessary parts to create a fast web server.
func Default ¶
func Default() *Application
Default returns a new Application instance. Unlike `New` this method prepares some things for you. std html templates from the "./templates" directory, session manager is attached with a default expiration of 7 days, recovery and (request) logger handlers(middleware) are being registered.
func New ¶
func New() *Application
New creates and returns a fresh empty Siris *Application instance.
func (*Application) AttachSessionManager ¶
func (app *Application) AttachSessionManager(provider string, cfg *sessions.ManagerConfig)
AttachSessionManager registers a session manager to the framework which is used for flash messages too.
See context.Session too.
func (*Application) AttachView ¶
func (app *Application) AttachView(viewEngine view.Engine) error
AttachView should be used to register view engines mapping to a root directory and the template file(s) extension. Returns an error on failure, otherwise nil.
func (*Application) Build ¶
func (app *Application) Build() (err error)
Build sets up, once, the framework. It builds the default router with its default macros and the template functions that are very-closed to siris.
func (*Application) ConfigurationReadOnly ¶
func (app *Application) ConfigurationReadOnly() context.ConfigurationReadOnly
ConfigurationReadOnly returns a structure which doesn't allow writing.
func (*Application) Configure ¶
func (app *Application) Configure(configurators ...Configurator) *Application
Configure can called when modifications to the framework instance needed. It accepts the framework instance and returns an error which if it's not nil it's printed to the logger. See configuration.go for more.
Returns itself in order to be used like app:= New().Configure(...)
func (*Application) ConfigureHost ¶
func (app *Application) ConfigureHost(configurators ...host.Configurator) *Application
ConfigureHost accepts one or more `host#Configuration`, these configurators functions can access the host created by `app.Run`, they're being executed when application is ready to being served to the public.
It's an alternative way to interact with a host that is automatically created by `app.Run`.
These "configurators" can work side-by-side with the `iris#Addr, iris#Server, iris#TLS, iris#AutoTLS, iris#Listener` final arguments("hostConfigs") too.
Note that these application's host "configurators" will be shared with the rest of the hosts that this app will may create (using `app.NewHost`), meaning that `app.NewHost` will execute these "configurators" everytime that is being called as well.
These "configurators" should be registered before the `app.Run` or `host.Serve/Listen` functions.
func (*Application) Listen ¶
func (app *Application) Listen(addr string)
Listen starts the standalone http server which listens to the addr parameter which as the form of host:port
Deprecated. Use `Run` instead.
func (*Application) ListenLETSENCRYPT ¶
func (app *Application) ListenLETSENCRYPT(addr string, cacheDirOptional ...string)
ListenLETSENCRYPT starts the server listening at the specific nat address using key & certification taken from the letsencrypt.org 's servers it's also starts a second 'http' server to redirect all 'http://$ADDR/$PATH' to the' https://$ADDR/$PATH' it creates a cache file to store the certifications, for performance reasons, this file by-default is "./certcache" if you skip the second parameter then the cache file is "./letsencrypt.cache" if you want to disable cache then simple pass as second argument an empty empty string ""
Deprecated. Use `Run` instead.
func (*Application) ListenTLS ¶
func (app *Application) ListenTLS(addr string, certFile, keyFile string)
ListenTLS starts the secure server with provided certificates, if you use this method the requests of the form of 'http://' will fail only https:// connections are allowed which listens to the addr parameter which as the form of host:port
Deprecated. Use `Run` instead.
func (*Application) ListenUNIX ¶
func (app *Application) ListenUNIX(socketFile string, mode os.FileMode)
ListenUNIX starts the server listening to the new requests using a 'socket file'. Note: this works only on unix.
Deprecated. Use `Run` instead.
func (*Application) Logger ¶
func (app *Application) Logger() *zap.SugaredLogger
Logger returns the zap logger instance(pointer) that is being used inside the "app".
func (*Application) NewHost ¶
func (app *Application) NewHost(srv *http.Server) *host.Supervisor
NewHost accepts a standar *http.Server object, completes the necessary missing parts of that "srv" and returns a new, ready-to-use, host (supervisor).
func (*Application) OnStatusCode ¶
func (app *Application) OnStatusCode(statusCode int, handler context.Handler)
OnStatusCode registers an error http status code based on the "statusCode" >= 400. The handler is being wrapepd by a generic handler which will try to reset the body if recorder was enabled and/or disable the gzip if gzip response recorder was active.
Deprecated. Use `OnErrorCode` instead.
func (*Application) Run ¶
func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error
Run builds the framework and starts the desired `Runner` with or without configuration edits.
Run should be called only once per Application instance, it blocks like http.Server.
If more than one server needed to run on the same siris instance then create a new host and run it manually by `go NewHost(*http.Server).Serve/ListenAndServe` etc... or use an already created host: h := NewHost(*http.Server) Run(Raw(h.ListenAndServe), WithoutBanner, WithCharset("UTF-8"))
The Application can go online with any type of server or siris's host with the help of the following runners: `Listener`, `Server`, `Addr`, `TLS`, `AutoTLS` and `Raw`.
func (*Application) SPA ¶
func (app *Application) SPA(assetHandler context.Handler)
SPA accepts an "assetHandler" which can be the result of an app.StaticHandler or app.StaticEmbeddedHandler. It wraps the router and checks: if it;s an asset, if the request contains "." (this behavior can be changed via /core/router.NewSPABuilder), if the request is index, redirects back to the "/" in order to let the root handler to be executed, if it's not an asset then it executes the router, so the rest of registered routes can be executed without conflicts with the file server ("assetHandler").
Use that instead of `StaticWeb` for root "/" file server.
Example: https://github.com/go-siris/siris/tree/master/_examples/beginner/file-server/single-page-application
func (*Application) Serve ¶
func (app *Application) Serve(l net.Listener) error
Serve serves incoming connections from the given listener.
Serve blocks until the given listener returns permanent error.
Deprecated. Use `Run` instead.
func (*Application) SessionManager ¶
func (app *Application) SessionManager() (*sessions.Manager, error)
SessionManager returns the session manager which contain a Start and Destroy methods used inside the context.Session().
It's ready to use after the RegisterSessions.
func (*Application) Shutdown ¶
func (app *Application) Shutdown(ctx stdContext.Context) error
Shutdown gracefully terminates all the application's server hosts. Returns an error on the first failure, otherwise nil.
func (*Application) View ¶
func (app *Application) View(writer io.Writer, filename string, layout string, bindingData interface{}) error
View executes and writes the result of a template file to the writer.
First parameter is the writer to write the parsed template. Second parameter is the relative, to templates directory, template filename, including extension. Third parameter is the layout, can be empty string. Forth parameter is the bindable data to the template, can be nil.
Use context.View to render templates to the client instead. Returns an error on failure, otherwise nil.
type Configurator ¶
type Configurator func(*Application)
Configurator is just an interface which accepts the framework instance.
It can be used to register a custom configuration with `Configure` in order to modify the framework instance.
Currently Configurator is being used to describe the configuration's fields values.
func WithCharset ¶
func WithCharset(charset string) Configurator
WithCharset sets the Charset setting.
See `Configuration`.
func WithConfiguration ¶
func WithConfiguration(c configuration.Configuration) Configurator
WithConfiguration sets the "c" values to the framework's configurations.
Usage: app.Run(siris.Addr(":8080"), siris.WithConfiguration(siris.Configuration{/* fields here */ })) or siris.WithConfiguration(siris.YAML("./cfg/iris.yml")) or siris.WithConfiguration(siris.TOML("./cfg/iris.tml"))
func WithOtherValue ¶
func WithOtherValue(key string, val interface{}) Configurator
WithOtherValue adds a value based on a key to the Other setting.
See `Configuration`.
func WithRemoteAddrHeader ¶
func WithRemoteAddrHeader(headerName string) Configurator
WithRemoteAddrHeader enables or adds a new or existing request header name that can be used to validate the client's real IP.
Existing values are: "X-Real-Ip": false, "X-Forwarded-For": false, "CF-Connecting-IP": false
Look `context.RemoteAddr()` for more.
func WithTimeFormat ¶
func WithTimeFormat(timeformat string) Configurator
WithTimeFormat sets the TimeFormat setting.
See `Configuration`.
func WithoutRemoteAddrHeader ¶
func WithoutRemoteAddrHeader(headerName string) Configurator
WithoutRemoteAddrHeader disables an existing request header name that can be used to validate the client's real IP.
Existing values are: "X-Real-Ip": false, "X-Forwarded-For": false, "CF-Connecting-IP": false
Look `context.RemoteAddr()` for more.
type Context ¶
Context is the midle-man server's "object" for the clients.
A New context is being acquired from a sync.Pool on each connection. The Context is the most important thing on the siris's http flow.
Developers send responses to the client's request through a Context. Developers get request information from the client's request by a Context.
type Handler ¶
A Handler responds to an HTTP request. It writes reply headers and data to the Context.ResponseWriter() and then return. Returning signals that the request is finished; it is not valid to use the Context after or concurrently with the completion of the Handler call.
Depending on the HTTP client software, HTTP protocol version, and any intermediaries between the client and the siris server, it may not be possible to read from the Context.Request().Body after writing to the context.ResponseWriter(). Cautious handlers should read the Context.Request().Body first, and then reply.
Except for reading the body, handlers should not modify the provided Context.
If Handler panics, the server (the caller of Handler) assumes that the effect of the panic was isolated to the active request. It recovers the panic, logs a stack trace to the server error log, and hangs up the connection.
type Party ¶
Party is just a group joiner of routes which have the same prefix and share same middleware(s) also. Party could also be named as 'Join' or 'Node' or 'Group' , Party chosen because it is fun.
Look the `core/router#APIBuilder` for its implementation.
A shortcut for the `core/router#Party`, useful when `PartyFunc` is being used.
type Runner ¶
type Runner func(*Application) error
Runner is just an interface which accepts the framework instance and returns an error.
It can be used to register a custom runner with `Run` in order to set the framework's server listen action.
Currently Runner is being used to declare the built'n server listeners.
See `Run` for more.
func Addr ¶
func Addr(addr string, hostConfigs ...host.Configurator) Runner
Addr can be used as an argument for the `Run` method. It accepts a host address which is used to build a server and a listener which listens on that host and port.
Addr should have the form of host:port, i.e localhost:8080 or :8080.
Second argument is optional, it accepts one or more `func(*host.Configurator)` that are being executed on that specific host that this function will create to start the server. Via host configurators you can configure the back-end host supervisor, i.e to add events for shutdown, serve or error. Look at the `ConfigureHost` too.
See `Run` for more.
func AutoTLS ¶
func AutoTLS(addr string, hostConfigs ...host.Configurator) Runner
AutoTLS can be used as an argument for the `Run` method. It will start the Application's secure server using certifications created on the fly by the "autocert" golang/x package, so localhost may not be working, use it at "production" machine.
Addr should have the form of host:port, i.e mydomain.com:443.
Second argument is optional, it accepts one or more `func(*host.Configurator)` that are being executed on that specific host that this function will create to start the server. Via host configurators you can configure the back-end host supervisor, i.e to add events for shutdown, serve or error. Look at the `ConfigureHost` too.
See `Run` for more.
func Listener ¶
func Listener(l net.Listener, hostConfigs ...host.Configurator) Runner
Listener can be used as an argument for the `Run` method. It can start a server with a custom net.Listener via server's `Serve`.
Second argument is optional, it accepts one or more `func(*host.Configurator)` that are being executed on that specific host that this function will create to start the server. Via host configurators you can configure the back-end host supervisor, i.e to add events for shutdown, serve or error. Look at the `ConfigureHost` too.
See `Run` for more.
func Raw ¶
Raw can be used as an argument for the `Run` method. It accepts any (listen) function that returns an error, this function should be block and return an error only when the server exited or a fatal error caused.
With this option you're not limited to the servers that Siris can run by-default.
See `Run` for more.
func Server ¶
func Server(srv *http.Server, hostConfigs ...host.Configurator) Runner
Server can be used as an argument for the `Run` method. It can start a server with a *http.Server.
Second argument is optional, it accepts one or more `func(*host.Configurator)` that are being executed on that specific host that this function will create to start the server. Via host configurators you can configure the back-end host supervisor, i.e to add events for shutdown, serve or error. Look at the `ConfigureHost` too.
See `Run` for more.
func TLS ¶
func TLS(addr string, certFile, keyFile string, hostConfigs ...host.Configurator) Runner
TLS can be used as an argument for the `Run` method. It will start the Application's secure server.
Use it like you used to use the http.ListenAndServeTLS function.
Addr should have the form of host:port, i.e localhost:443 or :443. CertFile & KeyFile should be filenames with their extensions.
Second argument is optional, it accepts one or more `func(*host.Configurator)` that are being executed on that specific host that this function will create to start the server. Via host configurators you can configure the back-end host supervisor, i.e to add events for shutdown, serve or error. Look at the `ConfigureHost` too.
See `Run` for more.
type Supervisor ¶
type Supervisor = host.Supervisor
Supervisor is a shortcut of the `host#Supervisor`. Used to add supervisor configurators on common Runners without the need of importing the `core/host` package.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
ruleset
Package ruleset provides the basics rules which are being extended by rules.
|
Package ruleset provides the basics rules which are being extended by rules. |
core
|
|
memstore
Package memstore contains a store which is just a collection of key-value entries with immutability capabilities.
|
Package memstore contains a store which is just a collection of key-value entries with immutability capabilities. |
Package sessions provider Usage: import( "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("memory", `{"cookieName":"gosessionid", "enableSetCookie,omitempty": true, "gclifetime":3600, "maxLifetime": 3600, "secure": false, "cookieLifeTime": 3600, "providerConfig": ""}`) go globalSessions.GC() } more docs: http://beego.me/docs/module/session.md Package sessions provider
|
Package sessions provider Usage: import( "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("memory", `{"cookieName":"gosessionid", "enableSetCookie,omitempty": true, "gclifetime":3600, "maxLifetime": 3600, "secure": false, "cookieLifeTime": 3600, "providerConfig": ""}`) go globalSessions.GC() } more docs: http://beego.me/docs/module/session.md Package sessions provider |
couchbase
Package couchbase for session provider depend on github.com/couchbaselabs/go-couchbasee go install github.com/couchbaselabs/go-couchbase Usage: import( _ "github.com/go-siris/siris/sessions/couchbase" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("couchbase", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md
|
Package couchbase for session provider depend on github.com/couchbaselabs/go-couchbasee go install github.com/couchbaselabs/go-couchbase Usage: import( _ "github.com/go-siris/siris/sessions/couchbase" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("couchbase", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md |
ledis
Package ledis provide session Provider
|
Package ledis provide session Provider |
memcache
Package memcache for session provider depend on github.com/bradfitz/gomemcache/memcache go install github.com/bradfitz/gomemcache/memcache Usage: import( _ "github.com/go-siris/siris/sessions/memcache" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("memcache", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md
|
Package memcache for session provider depend on github.com/bradfitz/gomemcache/memcache go install github.com/bradfitz/gomemcache/memcache Usage: import( _ "github.com/go-siris/siris/sessions/memcache" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("memcache", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md |
mysql
Package mysql for session provider depends on github.com/go-sql-driver/mysql: go install github.com/go-sql-driver/mysql mysql session support need create table as sql: CREATE TABLE `session` ( `session_key` char(64) NOT NULL, `session_data` blob, `session_expiry` int(11) unsigned NOT NULL, PRIMARY KEY (`session_key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; Usage: import( _ "github.com/go-siris/siris/sessions/mysql" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("mysql", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md
|
Package mysql for session provider depends on github.com/go-sql-driver/mysql: go install github.com/go-sql-driver/mysql mysql session support need create table as sql: CREATE TABLE `session` ( `session_key` char(64) NOT NULL, `session_data` blob, `session_expiry` int(11) unsigned NOT NULL, PRIMARY KEY (`session_key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; Usage: import( _ "github.com/go-siris/siris/sessions/mysql" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("mysql", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md |
postgres
Package postgres for session provider depends on github.com/lib/pq: go install github.com/lib/pq needs this table in your database: CREATE TABLE session ( session_key char(64) NOT NULL, session_data bytea, session_expiry timestamp NOT NULL, CONSTRAINT session_key PRIMARY KEY(session_key) ); will be activated with these settings in app.conf: SessionOn = true SessionProvider = postgresql SessionSavePath = "user=a password=b dbname=c sslmode=disable" SessionName = session Usage: import( _ "github.com/go-siris/siris/sessions/postgresql" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("postgresql", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md
|
Package postgres for session provider depends on github.com/lib/pq: go install github.com/lib/pq needs this table in your database: CREATE TABLE session ( session_key char(64) NOT NULL, session_data bytea, session_expiry timestamp NOT NULL, CONSTRAINT session_key PRIMARY KEY(session_key) ); will be activated with these settings in app.conf: SessionOn = true SessionProvider = postgresql SessionSavePath = "user=a password=b dbname=c sslmode=disable" SessionName = session Usage: import( _ "github.com/go-siris/siris/sessions/postgresql" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("postgresql", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md |
redis
Package redis for session provider depend on github.com/garyburd/redigo/redis go install github.com/garyburd/redigo/redis Usage: import( _ "github.com/go-siris/siris/sessions/redis" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("redis", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md
|
Package redis for session provider depend on github.com/garyburd/redigo/redis go install github.com/garyburd/redigo/redis Usage: import( _ "github.com/go-siris/siris/sessions/redis" "github.com/go-siris/siris/sessions" ) func init() { globalSessions, _ = sessions.NewManager("redis", “{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}“) go globalSessions.GC() } more docs: http://beego.me/docs/module/sessions.md |
Package typescript provides a typescript compiler with hot-reloader and optionally a cloud-based editor, called 'alm-tools'.
|
Package typescript provides a typescript compiler with hot-reloader and optionally a cloud-based editor, called 'alm-tools'. |