Composable framework for writing HTTP handlers in Go.

siesta

GoDoc build codecov

Siesta is a framework for writing composable HTTP handlers in Go. It supports typed URL parameters, middleware chains, and context passing.

Getting started

Siesta offers a Service type, which is a collection of middleware chains and handlers rooted at a base URI. There is no distinction between a middleware function and a handler function; they are all considered to be handlers and have access to the same arguments.

Siesta accepts many types of handlers. Refer to the GoDoc documentation for Service.Route for more information.

Here is the simple program in the examples directory. It demonstrates the use of a Service, routing, middleware, and a Context.

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/VividCortex/siesta"
)

func main() {
	// Create a new Service rooted at "/"
	service := siesta.NewService("/")

	// Route accepts normal http.Handlers.
	// The arguments are the method, path, description,
	// and the handler.
	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))
}

Siesta also provides utilities to manage URL parameters similar to the flag package. Refer to the params example for a demonstration.

Contributing

We only accept pull requests for minor fixes or improvements. This includes:

  • Small bug fixes
  • Typos
  • Documentation or comments

Please open issues to discuss new features. Pull requests for new features will be rejected, so we recommend forking the repository and making changes in your fork for your use case.

License

Siesta is licensed under the MIT license. The router, which is adapted from httprouter, is licensed separately.

Comments
  • Pull testing code into siesta?

    Pull testing code into siesta?

    I tend to think that a test harnesses should be placed with the library you're. In this case consider:

    1. Sticking the fake context into siesta so that users don't have to recreate it. ... Though arguable this is simple enough not to matter too much.
    2. I haven't found anything yet that allows me to test out the routes themselves. I wonder what would be a good method for that? Perhaps replace all handlers with test handler?
  • Difficulty using siesta with certain use cases.

    Difficulty using siesta with certain use cases.

    Consider a service that has several related endpoints and there is a ton of shared setup for these endpoints (authenticate user, grab appropriate databases, etc.). Then it's good to put these into the "pre" middleware. But what if you've got like 1 or 2 endpoints that don't need to do all of this? Is there any way that you can omit the preware? Otherwise we're doing a lot of work for no reason.

    One idea:

    //normal invocation
    service.Route("POST", "/envs", "Creates an env", createEnv)
    
    //replace preware
    service.WithPreware(nil).Route("POST", "/envs", "Creates an env", createEnv)
    
  • Run function after quit

    Run function after quit

    Hi, I'm trying to find a way to run a function after sending result. Let's suppose that I've to send the 200 OK quite fast but than continue processing data and doing insert on a slow service. I've added my AddPost at the end of the list but: if I set function without the quit (and it's in the previous one) function is never run if I set function as quit it runs but output is at the end of all.

    Can you please suggest a solution

    Thanks Maurizio

  • Make routing deterministic.

    Make routing deterministic.

    Right now routing involves iterating through a map to find a matching route. Since maps are not ordered, this can occasionally lead to unexpected matches. This also makes route testing more difficult.

    Make routing deterministic! And make the routes ordered so that they match in the order specified by the user.

  • how to get query parameters ?

    how to get query parameters ?

    hi,

    I can run sample examples , such as

    http://x.x.x.x/greeting/hello

    I want get parameters after ? , such as:

    http://x.x.x.x/greetings/?name=hello

    Is siesta support this format ?

    thanks.

  • Duplicated routing param and query string param?

    Duplicated routing param and query string param?

    What if someone has a /foo/:name/bar/ route and wants to have a name query string key, e.g. /foo/someName/bar/?name=otherName?

    name would be set to otherName in the parameters when you might expect someName.

    We should add a comment on this to the docs.

  • Add post-execution function

    Add post-execution function

    This adds Service.postExecutionFunc which is run at the end of every request, even if there's a panic within a handler.

    The main purpose for this is to support request logging. A postExecutionFunc will receive the siesta.Context used for the request and the http.Request itself. SiestaContext is now exported so you can range through its keys and values.

  • Accept '.' in regexp

    Accept '.' in regexp

    https://github.com/VividCortex/siesta/blob/7b04fbb4d6bba2abe4972e3886c4b66aa8de2f0b/service.go#L114

    expr = strings.Replace(expr, ">", ">[\\d\\w\\-\\_]+)", -1)
    

    I'm doing something like GET /<host> where host is an IP address. @xaprb, do you think it's a good idea to add periods to the regexp?

  • Pull common code into Siesta?

    Pull common code into Siesta?

    In an internal repo we have a post hook for writing a JSON response. I wonder if something like this should be pulled into an util directory within siesta. Then I could just specify that this code be used with service.AddPost(siesta.JsonResponseWriter). Then, by reading the JsonResponseWriter documentation I know that I can use status_code and response - life would be easy.

  • Skip empty items in slice parameters

    Skip empty items in slice parameters

    Empty items in slice parameters make parsing fail for numeric, boolean and duration types. Given that an empty value is not valid in any of those cases, we can safely ignore them. As a consequence, this update makes it possible to provide an entirely empty parameter, that would map to an empty slice. Before, there was no chance to make an empty slice other than not providing the parameter at all.

  • uriPath does not work with http.FileServer?

    uriPath does not work with http.FileServer?

    Is my understanding correct that uriPath is not a 'pattern' where it ends / map to just 1 HandlerFunc? func (s *Service) Route(.., uriPath, ...)

    as a result, siesta.Service.Route does not really behave like http.Handle / http.HandleFunc?

    package main
    
    import (
            "net/http"
    )
    
    func main() {
            http.Handle("/", http.FileServer(http.Dir("static")))
            http.ListenAndServe(":3000", nil)
    }
    
Related tags
Go Server/API micro framework, HTTP request router, multiplexer, mux
Go Server/API micro framework, HTTP request router, multiplexer, mux

?? gorouter Go Server/API micro framework, HTTP request router, multiplexer, mux. ?? ABOUT Contributors: Rafał Lorenz Want to contribute ? Feel free t

Dec 16, 2022
xujiajun/gorouter is a simple and fast HTTP router for Go. It is easy to build RESTful APIs and your web framework.

gorouter xujiajun/gorouter is a simple and fast HTTP router for Go. It is easy to build RESTful APIs and your web framework. Motivation I wanted a sim

Dec 8, 2022
Go HTTP request router and web framework benchmark

Go HTTP Router Benchmark This benchmark suite aims to compare the performance of HTTP request routers for Go by implementing the routing structure of

Dec 27, 2022
Bxog is a simple and fast HTTP router for Go (HTTP request multiplexer).

Bxog is a simple and fast HTTP router for Go (HTTP request multiplexer). Usage An example of using the multiplexer: package main import ( "io" "net

Dec 26, 2022
Simple Golang HTTP router
Simple Golang HTTP router

Bellt Simple Golang HTTP router Bellt Package implements a request router with the aim of managing controller actions based on fixed and parameterized

Sep 27, 2022
Lightning Fast HTTP Multiplexer
Lightning Fast HTTP Multiplexer

bone What is bone ? Bone is a lightweight and lightning fast HTTP Multiplexer for Golang. It support : URL Parameters REGEX Parameters Wildcard routes

Dec 17, 2022
FastRouter is a fast, flexible HTTP router written in Go.

FastRouter FastRouter is a fast, flexible HTTP router written in Go. FastRouter contains some customizable options, such as TrailingSlashesPolicy, Pan

Sep 27, 2022
Goji is a minimalistic and flexible HTTP request multiplexer for Go (golang)

Goji Goji is a HTTP request multiplexer, similar to net/http.ServeMux. It compares incoming requests to a list of registered Patterns, and dispatches

Jan 6, 2023
A high performance HTTP request router that scales well

HttpRouter HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go. In contrast to the

Dec 28, 2022
High-speed, flexible tree-based HTTP router for Go.

httptreemux High-speed, flexible, tree-based HTTP router for Go. This is inspired by Julien Schmidt's httprouter, in that it uses a patricia tree, but

Dec 28, 2022
:rotating_light: Is a lightweight, fast and extensible zero allocation HTTP router for Go used to create customizable frameworks.
:rotating_light: Is a lightweight, fast and extensible zero allocation HTTP router for Go used to create customizable frameworks.

LARS LARS is a fast radix-tree based, zero allocation, HTTP router for Go. view examples. If looking for a more pure Go solution, be sure to check out

Dec 27, 2022
A powerful HTTP router and URL matcher for building Go web servers with 🦍

gorilla/mux https://www.gorillatoolkit.org/pkg/mux Package gorilla/mux implements a request router and dispatcher for matching incoming requests to th

Jan 9, 2023
An extremely fast Go (golang) HTTP router that supports regular expression route matching. Comes with full support for building RESTful APIs.

ozzo-routing You may consider using go-rest-api to jumpstart your new RESTful applications with ozzo-routing. Description ozzo-routing is a Go package

Dec 31, 2022
Pure is a fast radix-tree based HTTP router
Pure is a fast radix-tree based HTTP router

package pure Pure is a fast radix-tree based HTTP router that sticks to the native implementations of Go's "net/http" package; in essence, keeping the

Dec 1, 2022
Go HTTP router

violetear Go HTTP router http://violetear.org Design Goals Keep it simple and small, avoiding extra complexity at all cost. KISS Support for static an

Dec 10, 2022
:tongue: CleverGo is a lightweight, feature rich and high performance HTTP router for Go.

CleverGo CleverGo is a lightweight, feature rich and trie based high performance HTTP request router. go get -u clevergo.tech/clevergo English 简体中文 Fe

Nov 17, 2022
Fast and flexible HTTP router
Fast and flexible HTTP router

treemux - fast and flexible HTTP router Basic example Debug logging CORS example Error handling Rate limiting using Redis Gzip compression OpenTelemet

Dec 27, 2022
Fast, simple, and lightweight HTTP router for Golang

Sariaf Fast, simple and lightweight HTTP router for golang Install go get -u github.com/majidsajadi/sariaf Features Lightweight compatible with net/ht

Aug 19, 2022
Mux is a simple and efficient route distributor that supports the net/http interface of the standard library.

Mux Mux is a simple and efficient route distributor that supports the net/http interface of the standard library. Routing data is stored in the prefix

Dec 12, 2022