fiber/router_bench_test.go
Fenny 99f95b2561
v1.9.6 (#360)
**🚀 Fiber `v1.9.6`**

Special thanks to @renanbastos93 & @renewerner87 for optimizing the current router.
Help use translate our API documentation by [clicking here](https://crowdin.com/project/gofiber)

🔥 New
- `AcquireCtx` / `ReleaseCtx`
The Ctx pool is now accessible for third-party packages
- Fiber docs merged [Russian](https://docs.gofiber.io/v/ru/) translations **84%**
- Fiber docs merged [Spanish](https://docs.gofiber.io/v/es/) translations  **65%**
- Fiber docs merged [French](https://docs.gofiber.io/v/fr/) translations  **40%**
- Fiber docs merged [German](https://docs.gofiber.io/v/de/) translations  **32%**
- Fiber docs merged [Portuguese](https://docs.gofiber.io/v/pt/) translations  **24%**

🩹 Fixes
- Hotfix for interpolated params in nested routes https://github.com/gofiber/fiber/issues/354
- Some `Ctx` methods didn't work correctly when called without an `*App` pointer.
- `ctx.Vary` sometimes added duplicates to the response header
- Improved router by ditching regexp and increased performance by **817%** without allocations.
```go
// Tested with 350 github API routes
Benchmark_Router_OLD-4      614   2467460 ns/op   68902 B/op   600 allocs/op
Benchmark_Router_NEW-4     3429    302033 ns/op       0 B/op     0 allocs/op
```

🧹 Updates
- Add context benchmarks
- Remove some unnecessary functions from `utils`
- Add router & param test cases
- Add new coffee supporters to readme
- Add third party middlewares to readme
- Add more comments to source code
- Cleanup some old helper functions

🧬 Middleware
- [gofiber/adaptor](https://github.com/gofiber/adaptor) `v0.0.1` Converter for net/http handlers to/from Fiber handlers
- [gofiber/session](https://github.com/gofiber/session) `v1.0.0` big improvements and support for storage providers
- [gofiber/logger](https://github.com/gofiber/logger) `v0.0.6` supports `${error}` param
- [gofiber/embed](https://github.com/gofiber/embed) `v0.0.9` minor improvements and support for directory browsing 

Co-authored-by: ReneWerner87 <renewerner87@googlemail.com>
2020-05-11 13:42:42 +02:00

615 lines
23 KiB
Go

// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
// 🤖 Github Repository: https://github.com/gofiber/fiber
// 📌 API Documentation: https://docs.gofiber.io
package fiber
// import (
// "testing"
// )
// var router_bench_app *App
// func init() {
// router_bench_app = New()
// h := func(c *Ctx) {}
// for _, r := range githubAPI {
// switch r.method {
// case "GET":
// router_bench_app.Get(r.path, h)
// case "POST":
// router_bench_app.Post(r.path, h)
// case "PUT":
// router_bench_app.Put(r.path, h)
// case "PATCH":
// router_bench_app.Patch(r.path, h)
// case "DELETE":
// router_bench_app.Delete(r.path, h)
// default:
// panic("Unknow HTTP method: " + r.method)
// }
// }
// }
// func Benchmark_Router_Github_Routes(b *testing.B) {
// var match bool
// var params []string
// for n := 0; n < b.N; n++ {
// for i := range testRoutes {
// match, params = matchRoute(testRoutes[i].method, testRoutes[i].path)
// }
// if match {
// if len(params) > 0 {
// }
// }
// }
// }
// func Benchmark_Router_Last_Route(b *testing.B) {
// var match bool
// var params []string
// for n := 0; n < b.N; n++ {
// match, params = matchRoute("DELETE", "/user/keys/1337")
// }
// if match {
// if len(params) > 0 {
// }
// }
// }
// func Benchmark_Router_First_Route(b *testing.B) {
// var match bool
// var params []string
// for n := 0; n < b.N; n++ {
// match, params = matchRoute("GET", "/authorizations")
// }
// if match {
// if len(params) > 0 {
// }
// }
// }
// func matchRoute(method, path string) (match bool, values []string) {
// mINT := methodINT[method]
// for i := range router_bench_app.routes[mINT] {
// match, values = router_bench_app.routes[mINT][i].matchRoute(path)
// if match {
// return true, values
// }
// }
// return
// }
// type testRoute struct {
// method string
// path string
// }
// var testRoutes = []testRoute{
// // OAuth Authorizations
// {"GET", "/authorizations"},
// {"GET", "/authorizations/1337"},
// {"POST", "/authorizations"},
// {"PUT", "/authorizations/clients/inf1nd873nf8912g9t"},
// {"PATCH", "/authorizations/1337"},
// {"DELETE", "/authorizations/1337"},
// {"GET", "/applications/2nds981mng6azl127y/tokens/sn108hbe1geheibf13f"},
// {"DELETE", "/applications/2nds981mng6azl127y/tokens"},
// {"DELETE", "/applications/2nds981mng6azl127y/tokens/sn108hbe1geheibf13f"},
// // Activity
// {"GET", "/events"},
// {"GET", "/repos/fenny/fiber/events"},
// {"GET", "/networks/fenny/fiber/events"},
// {"GET", "/orgs/gofiber/events"},
// {"GET", "/users/fenny/received_events"},
// {"GET", "/users/fenny/received_events/public"},
// {"GET", "/users/fenny/events"},
// {"GET", "/users/fenny/events/public"},
// {"GET", "/users/fenny/events/orgs/gofiber"},
// {"GET", "/feeds"},
// {"GET", "/notifications"},
// {"GET", "/repos/fenny/fiber/notifications"},
// {"PUT", "/notifications"},
// {"PUT", "/repos/fenny/fiber/notifications"},
// {"GET", "/notifications/threads/1337"},
// {"PATCH", "/notifications/threads/1337"},
// {"GET", "/notifications/threads/1337/subscription"},
// {"PUT", "/notifications/threads/1337/subscription"},
// {"DELETE", "/notifications/threads/1337/subscription"},
// {"GET", "/repos/fenny/fiber/stargazers"},
// {"GET", "/users/fenny/starred"},
// {"GET", "/user/starred"},
// {"GET", "/user/starred/fenny/fiber"},
// {"PUT", "/user/starred/fenny/fiber"},
// {"DELETE", "/user/starred/fenny/fiber"},
// {"GET", "/repos/fenny/fiber/subscribers"},
// {"GET", "/users/fenny/subscriptions"},
// {"GET", "/user/subscriptions"},
// {"GET", "/repos/fenny/fiber/subscription"},
// {"PUT", "/repos/fenny/fiber/subscription"},
// {"DELETE", "/repos/fenny/fiber/subscription"},
// {"GET", "/user/subscriptions/fenny/fiber"},
// {"PUT", "/user/subscriptions/fenny/fiber"},
// {"DELETE", "/user/subscriptions/fenny/fiber"},
// // Gists
// {"GET", "/users/fenny/gists"},
// {"GET", "/gists"},
// {"GET", "/gists/public"},
// {"GET", "/gists/starred"},
// {"GET", "/gists/1337"},
// {"POST", "/gists"},
// {"PATCH", "/gists/1337"},
// {"PUT", "/gists/1337/star"},
// {"DELETE", "/gists/1337/star"},
// {"GET", "/gists/1337/star"},
// {"POST", "/gists/1337/forks"},
// {"DELETE", "/gists/1337"},
// // Git Data
// {"GET", "/repos/fenny/fiber/git/blobs/v948b24g98ubngw9082bn02giub"},
// {"POST", "/repos/fenny/fiber/git/blobs"},
// {"GET", "/repos/fenny/fiber/git/commits/v948b24g98ubngw9082bn02giub"},
// {"POST", "/repos/fenny/fiber/git/commits"},
// {"GET", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
// {"GET", "/repos/fenny/fiber/git/refs"},
// {"POST", "/repos/fenny/fiber/git/refs"},
// {"PATCH", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
// {"DELETE", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
// {"GET", "/repos/fenny/fiber/git/tags/v948b24g98ubngw9082bn02giub"},
// {"POST", "/repos/fenny/fiber/git/tags"},
// {"GET", "/repos/fenny/fiber/git/trees/v948b24g98ubngw9082bn02giub"},
// {"POST", "/repos/fenny/fiber/git/trees"},
// // Issues
// {"GET", "/issues"},
// {"GET", "/user/issues"},
// {"GET", "/orgs/gofiber/issues"},
// {"GET", "/repos/fenny/fiber/issues"},
// {"GET", "/repos/fenny/fiber/issues/1000"},
// {"POST", "/repos/fenny/fiber/issues"},
// {"PATCH", "/repos/fenny/fiber/issues/1000"},
// {"GET", "/repos/fenny/fiber/assignees"},
// {"GET", "/repos/fenny/fiber/assignees/nic"},
// {"GET", "/repos/fenny/fiber/issues/1000/comments"},
// {"GET", "/repos/fenny/fiber/issues/comments"},
// {"GET", "/repos/fenny/fiber/issues/comments/1337"},
// {"POST", "/repos/fenny/fiber/issues/1000/comments"},
// {"PATCH", "/repos/fenny/fiber/issues/comments/1337"},
// {"DELETE", "/repos/fenny/fiber/issues/comments/1337"},
// {"GET", "/repos/fenny/fiber/issues/1000/events"},
// {"GET", "/repos/fenny/fiber/issues/events"},
// {"GET", "/repos/fenny/fiber/issues/events/1337"},
// {"GET", "/repos/fenny/fiber/labels"},
// {"GET", "/repos/fenny/fiber/labels/john"},
// {"POST", "/repos/fenny/fiber/labels"},
// {"PATCH", "/repos/fenny/fiber/labels/john"},
// {"DELETE", "/repos/fenny/fiber/labels/john"},
// {"GET", "/repos/fenny/fiber/issues/1000/labels"},
// {"POST", "/repos/fenny/fiber/issues/1000/labels"},
// {"DELETE", "/repos/fenny/fiber/issues/1000/labels/john"},
// {"PUT", "/repos/fenny/fiber/issues/1000/labels"},
// {"DELETE", "/repos/fenny/fiber/issues/1000/labels"},
// {"GET", "/repos/fenny/fiber/milestones/1000/labels"},
// {"GET", "/repos/fenny/fiber/milestones"},
// {"GET", "/repos/fenny/fiber/milestones/1000"},
// {"POST", "/repos/fenny/fiber/milestones"},
// {"PATCH", "/repos/fenny/fiber/milestones/1000"},
// {"DELETE", "/repos/fenny/fiber/milestones/1000"},
// // Miscellaneous
// {"GET", "/emojis"},
// {"GET", "/gitignore/templates"},
// {"GET", "/gitignore/templates/john"},
// {"POST", "/markdown"},
// {"POST", "/markdown/raw"},
// {"GET", "/meta"},
// {"GET", "/rate_limit"},
// // Organizations
// {"GET", "/users/fenny/orgs"},
// {"GET", "/user/orgs"},
// {"GET", "/orgs/gofiber"},
// {"PATCH", "/orgs/gofiber"},
// {"GET", "/orgs/gofiber/members"},
// {"GET", "/orgs/gofiber/members/fenny"},
// {"DELETE", "/orgs/gofiber/members/fenny"},
// {"GET", "/orgs/gofiber/public_members"},
// {"GET", "/orgs/gofiber/public_members/fenny"},
// {"PUT", "/orgs/gofiber/public_members/fenny"},
// {"DELETE", "/orgs/gofiber/public_members/fenny"},
// {"GET", "/orgs/gofiber/teams"},
// {"GET", "/teams/1337"},
// {"POST", "/orgs/gofiber/teams"},
// {"PATCH", "/teams/1337"},
// {"DELETE", "/teams/1337"},
// {"GET", "/teams/1337/members"},
// {"GET", "/teams/1337/members/fenny"},
// {"PUT", "/teams/1337/members/fenny"},
// {"DELETE", "/teams/1337/members/fenny"},
// {"GET", "/teams/1337/repos"},
// {"GET", "/teams/1337/repos/fenny/fiber"},
// {"PUT", "/teams/1337/repos/fenny/fiber"},
// {"DELETE", "/teams/1337/repos/fenny/fiber"},
// {"GET", "/user/teams"},
// // Pull Requests
// {"GET", "/repos/fenny/fiber/pulls"},
// {"GET", "/repos/fenny/fiber/pulls/1000"},
// {"POST", "/repos/fenny/fiber/pulls"},
// {"PATCH", "/repos/fenny/fiber/pulls/1000"},
// {"GET", "/repos/fenny/fiber/pulls/1000/commits"},
// {"GET", "/repos/fenny/fiber/pulls/1000/files"},
// {"GET", "/repos/fenny/fiber/pulls/1000/merge"},
// {"PUT", "/repos/fenny/fiber/pulls/1000/merge"},
// {"GET", "/repos/fenny/fiber/pulls/1000/comments"},
// {"GET", "/repos/fenny/fiber/pulls/comments"},
// {"GET", "/repos/fenny/fiber/pulls/comments/1000"},
// {"PUT", "/repos/fenny/fiber/pulls/1000/comments"},
// {"PATCH", "/repos/fenny/fiber/pulls/comments/1000"},
// {"DELETE", "/repos/fenny/fiber/pulls/comments/1000"},
// // Repositories
// {"GET", "/user/repos"},
// {"GET", "/users/fenny/repos"},
// {"GET", "/orgs/gofiber/repos"},
// {"GET", "/repositories"},
// {"POST", "/user/repos"},
// {"POST", "/orgs/gofiber/repos"},
// {"GET", "/repos/fenny/fiber"},
// {"PATCH", "/repos/fenny/fiber"},
// {"GET", "/repos/fenny/fiber/contributors"},
// {"GET", "/repos/fenny/fiber/languages"},
// {"GET", "/repos/fenny/fiber/teams"},
// {"GET", "/repos/fenny/fiber/tags"},
// {"GET", "/repos/fenny/fiber/branches"},
// {"GET", "/repos/fenny/fiber/branches/master"},
// {"DELETE", "/repos/fenny/fiber"},
// {"GET", "/repos/fenny/fiber/collaborators"},
// {"GET", "/repos/fenny/fiber/collaborators/fenny"},
// {"PUT", "/repos/fenny/fiber/collaborators/fenny"},
// {"DELETE", "/repos/fenny/fiber/collaborators/fenny"},
// {"GET", "/repos/fenny/fiber/comments"},
// {"GET", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub/comments"},
// {"POST", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub/comments"},
// {"GET", "/repos/fenny/fiber/comments/1337"},
// {"PATCH", "/repos/fenny/fiber/comments/1337"},
// {"DELETE", "/repos/fenny/fiber/comments/1337"},
// {"GET", "/repos/fenny/fiber/commits"},
// {"GET", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub"},
// {"GET", "/repos/fenny/fiber/readme"},
// {"GET", "/repos/fenny/fiber/contents/im/a/wildcard"},
// {"PUT", "/repos/fenny/fiber/contents/im/a/wildcard"},
// {"DELETE", "/repos/fenny/fiber/contents/im/a/wildcard"},
// {"GET", "/repos/fenny/fiber/gzip/google"},
// {"GET", "/repos/fenny/fiber/keys"},
// {"GET", "/repos/fenny/fiber/keys/1337"},
// {"POST", "/repos/fenny/fiber/keys"},
// {"PATCH", "/repos/fenny/fiber/keys/1337"},
// {"DELETE", "/repos/fenny/fiber/keys/1337"},
// {"GET", "/repos/fenny/fiber/downloads"},
// {"GET", "/repos/fenny/fiber/downloads/1337"},
// {"DELETE", "/repos/fenny/fiber/downloads/1337"},
// {"GET", "/repos/fenny/fiber/forks"},
// {"POST", "/repos/fenny/fiber/forks"},
// {"GET", "/repos/fenny/fiber/hooks"},
// {"GET", "/repos/fenny/fiber/hooks/1337"},
// {"POST", "/repos/fenny/fiber/hooks"},
// {"PATCH", "/repos/fenny/fiber/hooks/1337"},
// {"POST", "/repos/fenny/fiber/hooks/1337/tests"},
// {"DELETE", "/repos/fenny/fiber/hooks/1337"},
// {"POST", "/repos/fenny/fiber/merges"},
// {"GET", "/repos/fenny/fiber/releases"},
// {"GET", "/repos/fenny/fiber/releases/1337"},
// {"POST", "/repos/fenny/fiber/releases"},
// {"PATCH", "/repos/fenny/fiber/releases/1337"},
// {"DELETE", "/repos/fenny/fiber/releases/1337"},
// {"GET", "/repos/fenny/fiber/releases/1337/assets"},
// {"GET", "/repos/fenny/fiber/stats/contributors"},
// {"GET", "/repos/fenny/fiber/stats/commit_activity"},
// {"GET", "/repos/fenny/fiber/stats/code_frequency"},
// {"GET", "/repos/fenny/fiber/stats/participation"},
// {"GET", "/repos/fenny/fiber/stats/punch_card"},
// {"GET", "/repos/fenny/fiber/statuses/google"},
// {"POST", "/repos/fenny/fiber/statuses/google"},
// // Search
// {"GET", "/search/repositories"},
// {"GET", "/search/code"},
// {"GET", "/search/issues"},
// {"GET", "/search/users"},
// {"GET", "/legacy/issues/search/fenny/fibersitory/locked/finish"},
// {"GET", "/legacy/repos/search/finish"},
// {"GET", "/legacy/user/search/finish"},
// {"GET", "/legacy/user/email/info@gofiber.io"},
// // Users
// {"GET", "/users/fenny"},
// {"GET", "/user"},
// {"PATCH", "/user"},
// {"GET", "/users"},
// {"GET", "/user/emails"},
// {"POST", "/user/emails"},
// {"DELETE", "/user/emails"},
// {"GET", "/users/fenny/followers"},
// {"GET", "/user/followers"},
// {"GET", "/users/fenny/following"},
// {"GET", "/user/following"},
// {"GET", "/user/following/fenny"},
// {"GET", "/users/fenny/following/renan"},
// {"PUT", "/user/following/fenny"},
// {"DELETE", "/user/following/fenny"},
// {"GET", "/users/fenny/keys"},
// {"GET", "/user/keys"},
// {"GET", "/user/keys/1337"},
// {"POST", "/user/keys"},
// {"PATCH", "/user/keys/1337"},
// {"DELETE", "/user/keys/1337"},
// }
// var githubAPI = []testRoute{
// // OAuth Authorizations
// {"GET", "/authorizations"},
// {"GET", "/authorizations/:id"},
// {"POST", "/authorizations"},
// {"PUT", "/authorizations/clients/:client_id"},
// {"PATCH", "/authorizations/:id"},
// {"DELETE", "/authorizations/:id"},
// {"GET", "/applications/:client_id/tokens/:access_token"},
// {"DELETE", "/applications/:client_id/tokens"},
// {"DELETE", "/applications/:client_id/tokens/:access_token"},
// // Activity
// {"GET", "/events"},
// {"GET", "/repos/:owner/:repo/events"},
// {"GET", "/networks/:owner/:repo/events"},
// {"GET", "/orgs/:org/events"},
// {"GET", "/users/:user/received_events"},
// {"GET", "/users/:user/received_events/public"},
// {"GET", "/users/:user/events"},
// {"GET", "/users/:user/events/public"},
// {"GET", "/users/:user/events/orgs/:org"},
// {"GET", "/feeds"},
// {"GET", "/notifications"},
// {"GET", "/repos/:owner/:repo/notifications"},
// {"PUT", "/notifications"},
// {"PUT", "/repos/:owner/:repo/notifications"},
// {"GET", "/notifications/threads/:id"},
// {"PATCH", "/notifications/threads/:id"},
// {"GET", "/notifications/threads/:id/subscription"},
// {"PUT", "/notifications/threads/:id/subscription"},
// {"DELETE", "/notifications/threads/:id/subscription"},
// {"GET", "/repos/:owner/:repo/stargazers"},
// {"GET", "/users/:user/starred"},
// {"GET", "/user/starred"},
// {"GET", "/user/starred/:owner/:repo"},
// {"PUT", "/user/starred/:owner/:repo"},
// {"DELETE", "/user/starred/:owner/:repo"},
// {"GET", "/repos/:owner/:repo/subscribers"},
// {"GET", "/users/:user/subscriptions"},
// {"GET", "/user/subscriptions"},
// {"GET", "/repos/:owner/:repo/subscription"},
// {"PUT", "/repos/:owner/:repo/subscription"},
// {"DELETE", "/repos/:owner/:repo/subscription"},
// {"GET", "/user/subscriptions/:owner/:repo"},
// {"PUT", "/user/subscriptions/:owner/:repo"},
// {"DELETE", "/user/subscriptions/:owner/:repo"},
// // Gists
// {"GET", "/users/:user/gists"},
// {"GET", "/gists"},
// {"GET", "/gists/public"},
// {"GET", "/gists/starred"},
// {"GET", "/gists/:id"},
// {"POST", "/gists"},
// {"PATCH", "/gists/:id"},
// {"PUT", "/gists/:id/star"},
// {"DELETE", "/gists/:id/star"},
// {"GET", "/gists/:id/star"},
// {"POST", "/gists/:id/forks"},
// {"DELETE", "/gists/:id"},
// // Git Data
// {"GET", "/repos/:owner/:repo/git/blobs/:sha"},
// {"POST", "/repos/:owner/:repo/git/blobs"},
// {"GET", "/repos/:owner/:repo/git/commits/:sha"},
// {"POST", "/repos/:owner/:repo/git/commits"},
// {"GET", "/repos/:owner/:repo/git/refs/*"},
// {"GET", "/repos/:owner/:repo/git/refs"},
// {"POST", "/repos/:owner/:repo/git/refs"},
// {"PATCH", "/repos/:owner/:repo/git/refs/*"},
// {"DELETE", "/repos/:owner/:repo/git/refs/*"},
// {"GET", "/repos/:owner/:repo/git/tags/:sha"},
// {"POST", "/repos/:owner/:repo/git/tags"},
// {"GET", "/repos/:owner/:repo/git/trees/:sha"},
// {"POST", "/repos/:owner/:repo/git/trees"},
// // Issues
// {"GET", "/issues"},
// {"GET", "/user/issues"},
// {"GET", "/orgs/:org/issues"},
// {"GET", "/repos/:owner/:repo/issues"},
// {"GET", "/repos/:owner/:repo/issues/:number"},
// {"POST", "/repos/:owner/:repo/issues"},
// {"PATCH", "/repos/:owner/:repo/issues/:number"},
// {"GET", "/repos/:owner/:repo/assignees"},
// {"GET", "/repos/:owner/:repo/assignees/:assignee"},
// {"GET", "/repos/:owner/:repo/issues/:number/comments"},
// {"GET", "/repos/:owner/:repo/issues/comments"},
// {"GET", "/repos/:owner/:repo/issues/comments/:id"},
// {"POST", "/repos/:owner/:repo/issues/:number/comments"},
// {"PATCH", "/repos/:owner/:repo/issues/comments/:id"},
// {"DELETE", "/repos/:owner/:repo/issues/comments/:id"},
// {"GET", "/repos/:owner/:repo/issues/:number/events"},
// {"GET", "/repos/:owner/:repo/issues/events"},
// {"GET", "/repos/:owner/:repo/issues/events/:id"},
// {"GET", "/repos/:owner/:repo/labels"},
// {"GET", "/repos/:owner/:repo/labels/:name"},
// {"POST", "/repos/:owner/:repo/labels"},
// {"PATCH", "/repos/:owner/:repo/labels/:name"},
// {"DELETE", "/repos/:owner/:repo/labels/:name"},
// {"GET", "/repos/:owner/:repo/issues/:number/labels"},
// {"POST", "/repos/:owner/:repo/issues/:number/labels"},
// {"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"},
// {"PUT", "/repos/:owner/:repo/issues/:number/labels"},
// {"DELETE", "/repos/:owner/:repo/issues/:number/labels"},
// {"GET", "/repos/:owner/:repo/milestones/:number/labels"},
// {"GET", "/repos/:owner/:repo/milestones"},
// {"GET", "/repos/:owner/:repo/milestones/:number"},
// {"POST", "/repos/:owner/:repo/milestones"},
// {"PATCH", "/repos/:owner/:repo/milestones/:number"},
// {"DELETE", "/repos/:owner/:repo/milestones/:number"},
// // Miscellaneous
// {"GET", "/emojis"},
// {"GET", "/gitignore/templates"},
// {"GET", "/gitignore/templates/:name"},
// {"POST", "/markdown"},
// {"POST", "/markdown/raw"},
// {"GET", "/meta"},
// {"GET", "/rate_limit"},
// // Organizations
// {"GET", "/users/:user/orgs"},
// {"GET", "/user/orgs"},
// {"GET", "/orgs/:org"},
// {"PATCH", "/orgs/:org"},
// {"GET", "/orgs/:org/members"},
// {"GET", "/orgs/:org/members/:user"},
// {"DELETE", "/orgs/:org/members/:user"},
// {"GET", "/orgs/:org/public_members"},
// {"GET", "/orgs/:org/public_members/:user"},
// {"PUT", "/orgs/:org/public_members/:user"},
// {"DELETE", "/orgs/:org/public_members/:user"},
// {"GET", "/orgs/:org/teams"},
// {"GET", "/teams/:id"},
// {"POST", "/orgs/:org/teams"},
// {"PATCH", "/teams/:id"},
// {"DELETE", "/teams/:id"},
// {"GET", "/teams/:id/members"},
// {"GET", "/teams/:id/members/:user"},
// {"PUT", "/teams/:id/members/:user"},
// {"DELETE", "/teams/:id/members/:user"},
// {"GET", "/teams/:id/repos"},
// {"GET", "/teams/:id/repos/:owner/:repo"},
// {"PUT", "/teams/:id/repos/:owner/:repo"},
// {"DELETE", "/teams/:id/repos/:owner/:repo"},
// {"GET", "/user/teams"},
// // Pull Requests
// {"GET", "/repos/:owner/:repo/pulls"},
// {"GET", "/repos/:owner/:repo/pulls/:number"},
// {"POST", "/repos/:owner/:repo/pulls"},
// {"PATCH", "/repos/:owner/:repo/pulls/:number"},
// {"GET", "/repos/:owner/:repo/pulls/:number/commits"},
// {"GET", "/repos/:owner/:repo/pulls/:number/files"},
// {"GET", "/repos/:owner/:repo/pulls/:number/merge"},
// {"PUT", "/repos/:owner/:repo/pulls/:number/merge"},
// {"GET", "/repos/:owner/:repo/pulls/:number/comments"},
// {"GET", "/repos/:owner/:repo/pulls/comments"},
// {"GET", "/repos/:owner/:repo/pulls/comments/:number"},
// {"PUT", "/repos/:owner/:repo/pulls/:number/comments"},
// {"PATCH", "/repos/:owner/:repo/pulls/comments/:number"},
// {"DELETE", "/repos/:owner/:repo/pulls/comments/:number"},
// // Repositories
// {"GET", "/user/repos"},
// {"GET", "/users/:user/repos"},
// {"GET", "/orgs/:org/repos"},
// {"GET", "/repositories"},
// {"POST", "/user/repos"},
// {"POST", "/orgs/:org/repos"},
// {"GET", "/repos/:owner/:repo"},
// {"PATCH", "/repos/:owner/:repo"},
// {"GET", "/repos/:owner/:repo/contributors"},
// {"GET", "/repos/:owner/:repo/languages"},
// {"GET", "/repos/:owner/:repo/teams"},
// {"GET", "/repos/:owner/:repo/tags"},
// {"GET", "/repos/:owner/:repo/branches"},
// {"GET", "/repos/:owner/:repo/branches/:branch"},
// {"DELETE", "/repos/:owner/:repo"},
// {"GET", "/repos/:owner/:repo/collaborators"},
// {"GET", "/repos/:owner/:repo/collaborators/:user"},
// {"PUT", "/repos/:owner/:repo/collaborators/:user"},
// {"DELETE", "/repos/:owner/:repo/collaborators/:user"},
// {"GET", "/repos/:owner/:repo/comments"},
// {"GET", "/repos/:owner/:repo/commits/:sha/comments"},
// {"POST", "/repos/:owner/:repo/commits/:sha/comments"},
// {"GET", "/repos/:owner/:repo/comments/:id"},
// {"PATCH", "/repos/:owner/:repo/comments/:id"},
// {"DELETE", "/repos/:owner/:repo/comments/:id"},
// {"GET", "/repos/:owner/:repo/commits"},
// {"GET", "/repos/:owner/:repo/commits/:sha"},
// {"GET", "/repos/:owner/:repo/readme"},
// {"GET", "/repos/:owner/:repo/contents/*"},
// {"PUT", "/repos/:owner/:repo/contents/*"},
// {"DELETE", "/repos/:owner/:repo/contents/*"},
// {"GET", "/repos/:owner/:repo/:archive_format/:ref"},
// {"GET", "/repos/:owner/:repo/keys"},
// {"GET", "/repos/:owner/:repo/keys/:id"},
// {"POST", "/repos/:owner/:repo/keys"},
// {"PATCH", "/repos/:owner/:repo/keys/:id"},
// {"DELETE", "/repos/:owner/:repo/keys/:id"},
// {"GET", "/repos/:owner/:repo/downloads"},
// {"GET", "/repos/:owner/:repo/downloads/:id"},
// {"DELETE", "/repos/:owner/:repo/downloads/:id"},
// {"GET", "/repos/:owner/:repo/forks"},
// {"POST", "/repos/:owner/:repo/forks"},
// {"GET", "/repos/:owner/:repo/hooks"},
// {"GET", "/repos/:owner/:repo/hooks/:id"},
// {"POST", "/repos/:owner/:repo/hooks"},
// {"PATCH", "/repos/:owner/:repo/hooks/:id"},
// {"POST", "/repos/:owner/:repo/hooks/:id/tests"},
// {"DELETE", "/repos/:owner/:repo/hooks/:id"},
// {"POST", "/repos/:owner/:repo/merges"},
// {"GET", "/repos/:owner/:repo/releases"},
// {"GET", "/repos/:owner/:repo/releases/:id"},
// {"POST", "/repos/:owner/:repo/releases"},
// {"PATCH", "/repos/:owner/:repo/releases/:id"},
// {"DELETE", "/repos/:owner/:repo/releases/:id"},
// {"GET", "/repos/:owner/:repo/releases/:id/assets"},
// {"GET", "/repos/:owner/:repo/stats/contributors"},
// {"GET", "/repos/:owner/:repo/stats/commit_activity"},
// {"GET", "/repos/:owner/:repo/stats/code_frequency"},
// {"GET", "/repos/:owner/:repo/stats/participation"},
// {"GET", "/repos/:owner/:repo/stats/punch_card"},
// {"GET", "/repos/:owner/:repo/statuses/:ref"},
// {"POST", "/repos/:owner/:repo/statuses/:ref"},
// // Search
// {"GET", "/search/repositories"},
// {"GET", "/search/code"},
// {"GET", "/search/issues"},
// {"GET", "/search/users"},
// {"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword"},
// {"GET", "/legacy/repos/search/:keyword"},
// {"GET", "/legacy/user/search/:keyword"},
// {"GET", "/legacy/user/email/:email"},
// // Users
// {"GET", "/users/:user"},
// {"GET", "/user"},
// {"PATCH", "/user"},
// {"GET", "/users"},
// {"GET", "/user/emails"},
// {"POST", "/user/emails"},
// {"DELETE", "/user/emails"},
// {"GET", "/users/:user/followers"},
// {"GET", "/user/followers"},
// {"GET", "/users/:user/following"},
// {"GET", "/user/following"},
// {"GET", "/user/following/:user"},
// {"GET", "/users/:user/following/:target_user"},
// {"PUT", "/user/following/:user"},
// {"DELETE", "/user/following/:user"},
// {"GET", "/users/:user/keys"},
// {"GET", "/user/keys"},
// {"GET", "/user/keys/:id"},
// {"POST", "/user/keys"},
// {"PATCH", "/user/keys/:id"},
// {"DELETE", "/user/keys/:id"},
// }