Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-chi/chi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.1.0
Choose a base ref
...
head repository: go-chi/chi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.0.0
Choose a head ref

Commits on Apr 2, 2017

  1. Copy the full SHA
    157587f View commit details

Commits on Apr 14, 2017

  1. Production banner

    Peter Kieltyka committed Apr 14, 2017
    Copy the full SHA
    882fb16 View commit details
  2. Update link to used-in-production issue

    Peter Kieltyka committed Apr 14, 2017
    Copy the full SHA
    a57b1fb View commit details

Commits on May 13, 2017

  1. remove charset from application/json content type

    gabisurita authored and Peter Kieltyka committed May 13, 2017
    Copy the full SHA
    59bb6df View commit details
  2. render: fixes #193

    Peter Kieltyka committed May 13, 2017
    Copy the full SHA
    f262230 View commit details
  3. Copy the full SHA
    898d761 View commit details

Commits on May 15, 2017

  1. Remove trailing space, fix #197 thanks @dim

    Peter Kieltyka committed May 15, 2017
    Copy the full SHA
    5f645ae View commit details

Commits on May 22, 2017

  1. Update render/README

    Peter Kieltyka committed May 22, 2017
    Copy the full SHA
    35ec20b View commit details

Commits on May 31, 2017

  1. Add trace handler to the profiler

    Paweł Kowalczyk authored and Peter Kieltyka committed May 31, 2017
    Copy the full SHA
    7998bc7 View commit details

Commits on Jun 11, 2017

  1. Fix #185 to make best effort to parse content type

    Peter Kieltyka committed Jun 11, 2017
    Copy the full SHA
    dd7b63d View commit details
  2. Merge branch 'master' of github.com:pressly/chi

    Peter Kieltyka committed Jun 11, 2017
    Copy the full SHA
    9435d85 View commit details

Commits on Jun 15, 2017

  1. middleware/logger: use time.Since instead of Sub

    Signed-off-by: Daniel Dao <dqminh89@gmail.com>
    dqminh authored and Peter Kieltyka committed Jun 15, 2017
    Copy the full SHA
    d96632e View commit details

Commits on Jun 21, 2017

  1. v3 beta 1

    Peter Kieltyka authored and Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    8f717ba View commit details
  2. Introduce Method and MethodFunc to Router, supporting string defined …

    …http methods, along with example for custom http handler support
    Peter Kieltyka authored and Peter Kieltyka committed Jun 21, 2017

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    26633cb View commit details
  3. Remove FileServer from Mux, and offer as snippet helper code to users…

    … to build their own
    Peter Kieltyka authored and Peter Kieltyka committed Jun 21, 2017
    2

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6cbda14 View commit details
  4. v3.0.0 release

    Peter Kieltyka authored and Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    02e6bbd View commit details
  5. Copy the full SHA
    9d1fa8c View commit details
  6. Update import path in example, thank you @samwierema for the fix

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    7c1f98d View commit details
  7. Add support for LINK/UNLINK http methods, via Method()

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    34b5831 View commit details
  8. Update README

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    8fea38f View commit details
  9. Update README

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    9635270 View commit details
  10. Update _examples/rest with regexp example

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    23d479b View commit details
  11. Add no-store, must-revalidate to NoCache middleware

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    6de6386 View commit details
  12. While recovering from panic, print it's argument along with stack (#187)

    Vasily Kolobkov authored and Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    1ad86a4 View commit details
  13. docgen: fix reflection of pointer value for caller frame

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    5c9943c View commit details
  14. Update README with latest benchmarks of v3

    Peter Kieltyka committed Jun 21, 2017
    Copy the full SHA
    9678448 View commit details
44 changes: 32 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
# Changelog

## v3.0.0 (2017-06-21)

- Major update to chi library with many exciting updates, but also some *breaking changes*
- URL parameter syntax changed from `/:id` to `/{id}` for even more flexible routing, such as
`/articles/{month}-{day}-{year}-{slug}`, `/articles/{id}`, and `/articles/{id}.{ext}` on the
same router
- Support for regexp for routing patterns, in the form of `/{paramKey:regExp}` for example:
`r.Get("/articles/{name:[a-z]+}", h)` and `chi.URLParam(r, "name")`
- Add `Method` and `MethodFunc` to `chi.Router` to allow routing definitions such as
`r.Method("GET", "/", h)` which provides a cleaner interface for custom handlers like
in `_examples/custom-handler`
- Deprecating `mux#FileServer` helper function. Instead, we encourage users to create their
own using file handler with the stdlib, see `_examples/fileserver` for an example
- Add support for LINK/UNLINK http methods via `r.Method()` and `r.MethodFunc()`
- Moved the chi project to its own organization, to allow chi-related community packages to
be easily discovered and supported, at: https://github.com/go-chi
- *NOTE:* please update your import paths to `"github.com/go-chi/chi"`
- *NOTE:* chi v2 is still available at https://github.com/go-chi/chi/tree/v2


## v2.1.0 (2017-03-30)

- Minor improvements and update to the chi core library
- Introduced a brand new `chi/render` sub-package to complete the story of building
APIs to offer a pattern for managing well-defined request / response payloads. Please
check out the updated `_examples/rest` example for how it works.
APIs to offer a pattern for managing well-defined request / response payloads. Please
check out the updated `_examples/rest` example for how it works.
- Added `MethodNotAllowed(h http.HandlerFunc)` to chi.Router interface


## v2.0.0 (2017-01-06)

- After many months of v2 being in an RC state with many companies and users running it in
production, the inclusion of some improvements to the middlewares, we are very pleased to
announce v2.0.0 of chi.
production, the inclusion of some improvements to the middlewares, we are very pleased to
announce v2.0.0 of chi.


## v2.0.0-rc1 (2016-07-26)

- Huge update! chi v2 is a large refactor targetting Go 1.7+. As of Go 1.7, the popular
community `"net/context"` package has been included in the standard library as `"context"` and
utilized by `"net/http"` and `http.Request` to managing deadlines, cancelation signals and other
request-scoped values. We're very excited about the new context addition and are proud to
introduce chi v2, a minimal and powerful routing package for building large HTTP services,
with zero external dependencies. Chi focuses on idiomatic design and encourages the use of
stdlib HTTP handlers and middlwares.
community `"net/context"` package has been included in the standard library as `"context"` and
utilized by `"net/http"` and `http.Request` to managing deadlines, cancelation signals and other
request-scoped values. We're very excited about the new context addition and are proud to
introduce chi v2, a minimal and powerful routing package for building large HTTP services,
with zero external dependencies. Chi focuses on idiomatic design and encourages the use of
stdlib HTTP handlers and middlwares.
- chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc`
- chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()`
- chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`,
@@ -39,11 +59,11 @@ stdlib HTTP handlers and middlwares.

## v1.0.0 (2016-07-01)

- Released chi v1 stable https://github.com/pressly/chi/tree/v1.0.0 for Go 1.6 and older.
- Released chi v1 stable https://github.com/go-chi/chi/tree/v1.0.0 for Go 1.6 and older.


## v0.9.0 (2016-03-31)

- Reuse context objects via sync.Pool for zero-allocation routing [#33](https://github.com/pressly/chi/pull/33)
- Reuse context objects via sync.Pool for zero-allocation routing [#33](https://github.com/go-chi/chi/pull/33)
- BREAKING NOTE: due to subtle API changes, previously `chi.URLParams(ctx)["id"]` used to access url parameters
has changed to: `chi.URLParam(ctx, "id")`
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@
2. Download the sources and switch the working directory:

```bash
go get -u -d github.com/pressly/chi
cd $GOPATH/src/github.com/pressly/chi
go get -u -d github.com/go-chi/chi
cd $GOPATH/src/github.com/go-chi/chi
```

## Submitting a Pull Request
116 changes: 64 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# <img alt="chi" src="https://cdn.rawgit.com/pressly/chi/master/_examples/chi.svg" width="220" />
# <img alt="chi" src="https://cdn.rawgit.com/go-chi/chi/master/_examples/chi.svg" width="220" />


[![GoDoc Widget]][GoDoc] [![Travis Widget]][Travis]
@@ -14,35 +14,35 @@ public API service, which in turn powers all of our client-side applications.

The key considerations of chi's design are: project structure, maintainability, standard http
handlers (stdlib-only), developer productivity, and deconstructing a large system into many small
parts. The core router `github.com/pressly/chi` is quite small (less than 1000 LOC), but we've also
parts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also
included some useful/optional subpackages: `middleware`, `render` and `docgen`. We hope you enjoy it too!

## Install

`go get -u github.com/pressly/chi`
`go get -u github.com/go-chi/chi`


## Features

* **Lightweight** - cloc'd in <1000 LOC for the chi router
* **Fast** - yes, see [benchmarks](#benchmarks)
* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compat with `net/http`
* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http`
* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and subrouter mounting
* **Context control** - built on new `context` package, providing value chaining, cancelations and timeouts
* **Robust** - tested / used in production at Pressly.com, and many others
* **Robust** - in production at Pressly, CloudFlare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91))
* **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown
* **No external dependencies** - plain ol' Go 1.7+ stdlib + net/http


## Examples

* [rest](https://github.com/pressly/chi/blob/master/_examples/rest/main.go) - REST APIs made easy, productive and maintainable
* [logging](https://github.com/pressly/chi/blob/master/_examples/logging/main.go) - Easy structured logging for any backend
* [limits](https://github.com/pressly/chi/blob/master/_examples/limits/main.go) - Timeouts and Throttling
* [todos-resource](https://github.com/pressly/chi/blob/master/_examples/todos-resource/main.go) - Struct routers/handlers, an example of another code layout style
* [versions](https://github.com/pressly/chi/blob/master/_examples/versions/main.go) - Demo of `chi/render` subpkg
* [fileserver](https://github.com/pressly/chi/blob/master/_examples/fileserver/main.go) - Easily serve static files
* [graceful](https://github.com/pressly/chi/blob/master/_examples/graceful/main.go) - Graceful context signaling and server shutdown
* [rest](https://github.com/go-chi/chi/blob/master/_examples/rest/main.go) - REST APIs made easy, productive and maintainable
* [logging](https://github.com/go-chi/chi/blob/master/_examples/logging/main.go) - Easy structured logging for any backend
* [limits](https://github.com/go-chi/chi/blob/master/_examples/limits/main.go) - Timeouts and Throttling
* [todos-resource](https://github.com/go-chi/chi/blob/master/_examples/todos-resource/main.go) - Struct routers/handlers, an example of another code layout style
* [versions](https://github.com/go-chi/chi/blob/master/_examples/versions/main.go) - Demo of `chi/render` subpkg
* [fileserver](https://github.com/go-chi/chi/blob/master/_examples/fileserver/main.go) - Easily serve static files
* [graceful](https://github.com/go-chi/chi/blob/master/_examples/graceful/main.go) - Graceful context signaling and server shutdown


**As easy as:**
@@ -52,7 +52,7 @@ package main

import (
"net/http"
"github.com/pressly/chi"
"github.com/go-chi/chi"
)

func main() {
@@ -67,8 +67,8 @@ func main() {
**REST Preview:**

Here is a little preview of how routing looks like with chi. Also take a look at the generated routing docs
in JSON ([routes.json](https://github.com/pressly/chi/blob/master/_examples/rest/routes.json)) and in
Markdown ([routes.md](https://github.com/pressly/chi/blob/master/_examples/rest/routes.md)).
in JSON ([routes.json](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.json)) and in
Markdown ([routes.md](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.md)).

I highly recommend reading the source of the [examples](#examples) listed above, they will show you all the features
of chi and serve as a good form of documentation.
@@ -77,8 +77,8 @@ of chi and serve as a good form of documentation.
import (
//...
"context"
"github.com/pressly/chi"
"github.com/pressly/chi/middleware"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
)

func main() {
@@ -90,10 +90,6 @@ func main() {
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)

// When a client closes their connection midway through a request, the
// http.CloseNotifier will cancel the request context (ctx).
r.Use(middleware.CloseNotify)

// Set a timeout value on the request context (ctx), that will signal
// through ctx.Done() that the request has timed out and further
// processing should be stopped.
@@ -105,15 +101,21 @@ func main() {

// RESTy routes for "articles" resource
r.Route("/articles", func(r chi.Router) {
r.With(paginate).Get("/", listArticles) // GET /articles
r.Post("/", createArticle) // POST /articles
r.Get("/search", searchArticles) // GET /articles/search
r.With(paginate).Get("/", listArticles) // GET /articles
r.With(paginate).Get("/{month}-{day}-{year}", listArticlesByDate) // GET /articles/01-16-2017

r.Post("/", createArticle) // POST /articles
r.Get("/search", searchArticles) // GET /articles/search

r.Route("/:articleID", func(r chi.Router) {
// Regexp url parameters:
r.Get("/{articleSlug:[a-z-]+}", getArticleBySlug) // GET /articles/home-is-toronto

// Subrouters:
r.Route("/{articleID}", func(r chi.Router) {
r.Use(ArticleCtx)
r.Get("/", getArticle) // GET /articles/123
r.Put("/", updateArticle) // PUT /articles/123
r.Delete("/", deleteArticle) // DELETE /articles/123
r.Get("/", getArticle) // GET /articles/123
r.Put("/", updateArticle) // PUT /articles/123
r.Delete("/", deleteArticle) // DELETE /articles/123
})
})

@@ -204,6 +206,11 @@ type Router interface {
Handle(pattern string, h http.Handler)
HandleFunc(pattern string, h http.HandlerFunc)

// Method and MethodFunc adds routes for `pattern` that matches
// the `method` HTTP method.
Method(method, pattern string, h http.Handler)
MethodFunc(method, pattern string, h http.HandlerFunc)

// HTTP-method routing along `pattern`
Connect(pattern string, h http.HandlerFunc)
Delete(pattern string, h http.HandlerFunc)
@@ -218,6 +225,10 @@ type Router interface {
// NotFound defines a handler to respond whenever a route could
// not be found.
NotFound(h http.HandlerFunc)

// MethodNotAllowed defines a handler to respond whenever a method is
// not allowed.
MethodNotAllowed(h http.HandlerFunc)
}

// Routes interface adds two methods for router traversal, which is also
@@ -232,7 +243,7 @@ type Routes interface {
```

Each routing method accepts a URL `pattern` and chain of `handlers`. The URL pattern
supports named params (ie. `/users/:userID`) and wildcards (ie. `/admin/*`). URL parameters
supports named params (ie. `/users/{userID}`) and wildcards (ie. `/admin/*`). URL parameters
can be fetched at runtime by calling `chi.URLParam(r, "userID")` for named parameters
and `chi.URLParam(r, "*")` for a wildcard parameter.

@@ -283,7 +294,7 @@ are able to access the same information.
```go
// HTTP handler accessing the url routing parameters.
func MyRequestHandler(w http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "userID") // from a route like /users/:userID
userID := chi.URLParam(r, "userID") // from a route like /users/{userID}

ctx := r.Context()
key := ctx.Value("key").(string)
@@ -317,11 +328,12 @@ with `net/http` can be used with chi's mux.
| Heartbeat | Monitoring endpoint to check the servers pulse. |
----------------------------------------------------------------------------------------------------------

Other cool net/http middlewares:
Other cool community net/http middlewares:

* [jwtauth](https://github.com/goware/jwtauth) - JWT authenticator
* [cors](https://github.com/goware/cors) - CORS middleware
* [httpcoala](https://github.com/goware/httpcoala) - Request coalescer
* [chi-authz](https://github.com/casbin/chi-authz) - Authorization middleware built on https://github.com/hsluoyz/casbin

please [submit a PR](./CONTRIBUTING.md) if you'd like to include a link to a chi middleware

@@ -343,25 +355,25 @@ and..

The benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark

Comparison with other routers (as of Jan 7/17): https://gist.github.com/pkieltyka/d0814d5396c996cb3ff8076399583d1f
Comparison with other routers (as of June 21, 2017): https://gist.github.com/pkieltyka/c089f309abeb179cfc4deaa519956d8c

```shell
BenchmarkChi_Param 5000000 398 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Param5 3000000 556 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Param20 1000000 1184 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParamWrite 3000000 443 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubStatic 3000000 427 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubParam 3000000 565 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubAll 10000 122143 ns/op 61716 B/op 406 allocs/op
BenchmarkChi_GPlusStatic 5000000 383 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlusParam 3000000 431 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlus2Params 3000000 500 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlusAll 200000 6410 ns/op 3952 B/op 26 allocs/op
BenchmarkChi_ParseStatic 5000000 384 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParseParam 3000000 415 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Parse2Params 3000000 450 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParseAll 100000 12124 ns/op 7904 B/op 52 allocs/op
BenchmarkChi_StaticAll 20000 78501 ns/op 47731 B/op 314 allocs/op
BenchmarkChi_Param 3000000 427 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Param5 2000000 631 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Param20 1000000 1343 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParamWrite 3000000 477 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubStatic 3000000 452 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubParam 2000000 616 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GithubAll 10000 130637 ns/op 61716 B/op 406 allocs/op
BenchmarkChi_GPlusStatic 3000000 415 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlusParam 3000000 465 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlus2Params 3000000 548 ns/op 304 B/op 2 allocs/op
BenchmarkChi_GPlusAll 200000 6895 ns/op 3952 B/op 26 allocs/op
BenchmarkChi_ParseStatic 3000000 407 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParseParam 3000000 451 ns/op 304 B/op 2 allocs/op
BenchmarkChi_Parse2Params 3000000 504 ns/op 304 B/op 2 allocs/op
BenchmarkChi_ParseAll 100000 13221 ns/op 7904 B/op 52 allocs/op
BenchmarkChi_StaticAll 20000 84327 ns/op 47731 B/op 314 allocs/op
```

NOTE: the allocs in the benchmark above are from the calls to http.Request's
@@ -404,7 +416,7 @@ Copyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka)

Licensed under [MIT License](./LICENSE)

[GoDoc]: https://godoc.org/github.com/pressly/chi
[GoDoc Widget]: https://godoc.org/github.com/pressly/chi?status.svg
[Travis]: https://travis-ci.org/pressly/chi
[Travis Widget]: https://travis-ci.org/pressly/chi.svg?branch=master
[GoDoc]: https://godoc.org/github.com/go-chi/chi
[GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg
[Travis]: https://travis-ci.org/go-chi/chi
[Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master
35 changes: 35 additions & 0 deletions _examples/custom-handler/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"errors"
"net/http"

"github.com/go-chi/chi"
)

type Handler func(w http.ResponseWriter, r *http.Request) error

func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := h(w, r); err != nil {
// handle returned error here.
w.WriteHeader(503)
w.Write([]byte("bad"))
}
}

func main() {
r := chi.NewRouter()
r.Method("GET", "/", Handler(fooHandler))
http.ListenAndServe(":3333", r)
}

func fooHandler(w http.ResponseWriter, r *http.Request) error {
q := r.URL.Query().Get("err")

if q != "" {
return errors.New(q)
}

w.Write([]byte("foo"))
return nil
}
25 changes: 23 additions & 2 deletions _examples/fileserver/main.go
Original file line number Diff line number Diff line change
@@ -4,8 +4,9 @@ import (
"net/http"
"os"
"path/filepath"
"strings"

"github.com/pressly/chi"
"github.com/go-chi/chi"
)

func main() {
@@ -17,7 +18,27 @@ func main() {

workDir, _ := os.Getwd()
filesDir := filepath.Join(workDir, "files")
r.FileServer("/files", http.Dir(filesDir))
FileServer(r, "/files", http.Dir(filesDir))

http.ListenAndServe(":3333", r)
}

// FileServer conveniently sets up a http.FileServer handler to serve
// static files from a http.FileSystem.
func FileServer(r chi.Router, path string, root http.FileSystem) {
if strings.ContainsAny(path, ":*") {
panic("FileServer does not permit URL parameters.")
}

fs := http.StripPrefix(path, http.FileServer(root))

if path != "/" && path[len(path)-1] != '/' {
r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP)
path += "/"
}
path += "*"

r.Get(path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fs.ServeHTTP(w, r)
}))
}
Loading