func main() { // Create a new Service rooted at "/" service := siesta.NewService("/") // Route accepts normal http.Handlers. service.Route("GET", "/", "Sends 'Hello, world!'", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, world!") }) // Let's create some simple "middleware." // This handler will accept a Context argument and will add the current // time to it. timestamper := func(c siesta.Context, w http.ResponseWriter, r *http.Request) { c.Set("start", time.Now()) } // This is the handler that will actually send data back to the client. // It also takes a Context argument so it can get the timestamp from the // previous handler. timeHandler := func(c siesta.Context, w http.ResponseWriter, r *http.Request) { start := c.Get("start").(time.Time) delta := time.Now().Sub(start) fmt.Fprintf(w, "That took %v.\n", delta) } // We can compose these handlers together. timeHandlers := siesta.Compose(timestamper, timeHandler) // Finally, we'll add the new handler we created using composition to a new route. service.Route("GET", "/time", "Sends how long it took to send a message", timeHandlers) // service is an http.Handler, so we can pass it directly to ListenAndServe. log.Fatal(http.ListenAndServe(":8080", service)) }
func main() { // Create a new service rooted at /. service := siesta.NewService("/") // requestIdentifier assigns an ID to every request // and adds it to the context for that request. // This is useful for logging. service.AddPre(requestIdentifier) // Add access to the state via the context in every handler. service.AddPre(func(c siesta.Context, w http.ResponseWriter, r *http.Request) { c.Set("db", state) }) // We'll add the authenticator middleware to the "pre" chain. // It will ensure that every request has a valid token. service.AddPre(authenticator) // Response generation service.AddPost(responseGenerator) service.AddPost(responseWriter) // Custom 404 handler service.SetNotFound(func(c siesta.Context, w http.ResponseWriter, r *http.Request) { c.Set("status-code", http.StatusNotFound) c.Set("error", "not found") }) // Routes service.Route("GET", "/resources/:resourceID", "Retrieves a resource", getResource) log.Println("Listening on :8080") panic(http.ListenAndServe(":8080", service)) }
func main() { // Create a new Service rooted at "/" service := siesta.NewService("/") // Here's a handler that uses a URL parameter. // Example: GET /greet/Bob service.Route("GET", "/greet/:name", "Greets with a name.", func(w http.ResponseWriter, r *http.Request) { var params siesta.Params name := params.String("name", "", "Person's name") err := params.Parse(r.Form) if err != nil { log.Println("Error parsing parameters!", err) return } fmt.Fprintf(w, "Hello, %s!", *name) }, ) // Here's a handler that uses a query string parameter. // Example: GET /square?number=10 service.Route("GET", "/square", "Prints the square of a number.", func(w http.ResponseWriter, r *http.Request) { var params siesta.Params number := params.Int("number", 0, "A number to square") err := params.Parse(r.Form) if err != nil { log.Println("Error parsing parameters!", err) return } fmt.Fprintf(w, "%d * %d = %d.", *number, *number, (*number)*(*number)) }, ) // We can also use both URL and query string parameters. // Example: GET /exponentiate/10?power=10 service.Route("GET", "/exponentiate/:number", "Exponentiates a number.", func(w http.ResponseWriter, r *http.Request) { var params siesta.Params number := params.Float64("number", 0, "A number to exponentiate") power := params.Float64("power", 1, "Power") err := params.Parse(r.Form) if err != nil { log.Println("Error parsing parameters!", err) return } fmt.Fprintf(w, "%g ^ %g = %g.", *number, *power, math.Pow(*number, *power)) }, ) // service is an http.Handler, so we can pass it directly to ListenAndServe. log.Fatal(http.ListenAndServe(":8080", service)) }
func initSiesta() { h := siesta.NewService("/") h.Route("GET", "/", "", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Hello, World") }) h.Route("GET", "/:name", "", func(w http.ResponseWriter, r *http.Request) { var params siesta.Params name := params.String("name", "", "") params.Parse(r.Form) w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Hello, %s", *name) }) registerHandler("siesta", h) }
func (s *APIServer) Run() { service := siesta.NewService("/") service.AddPre(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", r.Header.Get("Access-Control-Request-Headers")) }) service.AddPost(func(c siesta.Context, w http.ResponseWriter, r *http.Request, q func()) { resp := c.Get(responseKey) err, _ := c.Get(errorKey).(string) if resp == nil && err == "" { return } enc := json.NewEncoder(w) enc.Encode(APIResponse{ Data: resp, Error: err, }) }) service.Route("GET", "/", "Default page", func(c siesta.Context, w http.ResponseWriter, r *http.Request) { c.Set(responseKey, "Welcome to the Cistern API!") }) service.Route("GET", "/devices", "Lists sources", func(c siesta.Context, w http.ResponseWriter, r *http.Request) { type ipHostname struct { IP string `json:"ip"` Hostname string `json:"hostname,omitempty"` } devices := []ipHostname{} for _, dev := range s.deviceRegistry.Devices() { devices = append(devices, ipHostname{ IP: dev.IP().String(), Hostname: dev.Hostname(), }) } c.Set(responseKey, devices) }) service.Route("GET", "/devices/:device/metrics", "Lists metrics for a device", func(c siesta.Context, w http.ResponseWriter, r *http.Request) { var params siesta.Params device := params.String("device", "", "Device name") err := params.Parse(r.Form) if err != nil { c.Set(errorKey, err.Error()) return } address := net.ParseIP(*device) dev, present := s.deviceRegistry.Lookup(address) if !present { c.Set(errorKey, "device not found") return } c.Set(responseKey, dev.Metrics()) }) service.Route("GET", "/devices/:device/flows", "Lists top flows for a device", func(c siesta.Context, w http.ResponseWriter, r *http.Request) { var params siesta.Params device := params.String("device", "", "Device name") err := params.Parse(r.Form) if err != nil { c.Set(errorKey, err.Error()) return } address := net.ParseIP(*device) dev, present := s.deviceRegistry.Lookup(address) if !present { c.Set(errorKey, "device not found") return } type flowsResponse struct { ByBytes []flows.Flow `json:"byBytes"` ByPackets []flows.Flow `json:"byPackets"` } topTalkers := dev.TopTalkers() if topTalkers == nil { c.Set(errorKey, "No active flows") return } resp := flowsResponse{ ByBytes: topTalkers.ByBytes(), ByPackets: topTalkers.ByPackets(), } c.Set(responseKey, resp) }) service.Route("OPTIONS", "/series/query", "Accepts an OPTIONS request", func(w http.ResponseWriter, r *http.Request) { // Doesn't do anything }) service.Route("POST", "/series/query", "Lists metrics for a device", s.querySeriesRoute()) http.Handle("/", service) go http.ListenAndServe(s.addr, nil) }