Guide · Open source
How to use Martini: Go web routes and handlers
Updated · written with AI from the project's own documentation and checked against our catalogue data
Martini is a Go package for writing web applications and services. You register handler functions for URL routes, and Martini supplies the arguments they need, such as the request or a URL parameter, through dependency injection. This guide walks through installing it, running a first server, and using routes, handlers, services and groups. The project's README states that the framework is no longer maintained, so read this as a guide to a mature, frozen codebase rather than a recommendation for new production work.
Quick start
- 1Install Go. Install Go 1.1 or greater and set up your GOPATH, as the README describes.
- 2Install Martini. Run go get github.com/go-martini/martini to add the package.
- 3Create server.go. Write a main function that calls martini.Classic() and registers a GET route on /.
- 4Run the server. Run go run server.go and open localhost:3000 in your browser.
- 5Add routes and parameters. Register more handlers with Get, Post and the other route methods, and read URL values with martini.Params.
- 6Use groups and services. Group related routes with Group and map shared services with Map or MapTo.
Install Martini and run a first server
Martini requires Go 1.1 or greater, according to the README. After installing Go and setting up your GOPATH, create a file called server.go. The example below uses martini.Classic(), which provides reasonable defaults for most web applications, and registers one GET route on /.
- Install the package with go get github.com/go-martini/martini.
- Start the example with go run server.go.
- The README says the server will be running on localhost:3000.
package main
import "github.com/go-martini/martini"
func main() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
}Write handlers and return values
A handler is basically any kind of callable function. If a handler returns a string, Martini writes it to the response as the body. If it returns an int and a string, the int is used as the HTTP status code.
- Returning a string gives HTTP 200 with that text.
- Returning (int, string) lets you set the status, for example 418 with a message.
- Handlers can also take http.ResponseWriter and *http.Request as arguments, and Martini injects them.
m.Get("/", func() (int, string) {
return 418, "i'm a teapot" // HTTP 418 : "i'm a teapot"
})Define routes, named parameters and patterns
A route is an HTTP method paired with a URL-matching pattern. Martini provides methods for Get, Patch, Post, Put, Delete and Options, plus NotFound for 404 handling. Routes are matched in the order they are defined, and the first match is invoked.
Named parameters are read with the martini.Params service. The README also shows glob patterns (**) and regular expressions with named groups.
- Named parameter: /hello/:name, read with params["name"].
- Glob: /hello/**, read with params["_1"].
- Regular expressions use Go regexp syntax, as in (?P<name>[a-zA-Z]+).
m.Get("/hello/:name", func(params martini.Params) string {
return "Hello " + params["name"]
})Stack handlers and group routes
You can pass several handlers to one route. Earlier handlers run first, so an authorization check can run before the main handler. The README notes the main handler runs as long as the authorization handler does not write a response.
Route groups are added with the Group method. You can also pass middleware to a group as extra arguments after the group function.
- Stacking: m.Get("/secret", authorize, handler).
- Groups: m.Group("/books", func(r martini.Router) { ... }).
- Group middleware: pass MyMiddleware1 and MyMiddleware2 after the group function.
m.Group("/books", func(r martini.Router) {
r.Get("/:id", GetBooks)
r.Post("/new", NewBook)
}, MyMiddleware1, MyMiddleware2)Share services with dependency injection
Services are objects available to be injected into a handler's argument list. You can map a service globally on the Martini instance, so every handler receives it by type, or per request from inside a handler using martini.Context. You can also map a value to an interface, such as wrapping http.ResponseWriter.
The README lists services included with Classic, including *log.Logger, martini.Params, martini.Route, martini.Routes, http.ResponseWriter and *http.Request.
- Global: m.Map(db) makes the value available as *MyDatabase.
- Per request: c.Map(logger) inside a handler.
- Interface: c.MapTo(rw, (*http.ResponseWriter)(nil)).
db := &MyDatabase{}
m := martini.Classic()
m.Map(db)
m.Run()What people use it for
- Defining a small set of HTTP routes for a simple Go API or demo service.
- Adding an authorization check in front of specific routes by stacking handlers.
- Organising book or resource endpoints into a route group with shared middleware.
- Serving static files or default documents, such as AngularJS apps in HTML5 mode, as the README describes.
- Reading or maintaining an existing Martini codebase.
Frequently asked questions
Is Martini still maintained?
No. The README states that the martini framework is no longer maintained. The project's analysis describes it as a mature but frozen project.
What do I need to install Martini?
The README says Go 1.1 or greater is required. Install the package with go get github.com/go-martini/martini, then run your server with go run server.go.
Is Martini free to use?
Martini is released under the MIT licence, as listed on its project page. The licence permits use, so check the LICENSE file in the repository for the full terms.
How do I get help if something breaks?
The README points to a mailing list, a demo video, questions tagged martini on Stackoverflow, and the GoDoc documentation for the package.
What are good alternatives to Martini?
Projects comparable to Martini include Gin, Echo, Chi and Gorilla Mux. Since Martini is no longer maintained, these are the options to evaluate for new projects.
Should I use Martini for a new production project?
The README and project analysis advise against it for new production projects, because the framework is no longer maintained and the last push was 2022-03-29. Teams needing security fixes or new Go version support should pick an actively maintained alternative.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
Martini suits Go developers who want a small, simple way to define routes and handlers, and anyone reading or maintaining an existing Martini codebase or learning how dependency injection and middleware work. Because the README says it is no longer maintained, new production projects and teams that need security fixes or new Go version support should choose an actively maintained framework such as Gin, Echo, Chi or Gorilla Mux.
Install options & downloads