{"id":16042515,"url":"https://github.com/naughtygopher/webgo","last_synced_at":"2025-05-16T12:00:19.416Z","repository":{"id":37801250,"uuid":"48094950","full_name":"naughtygopher/webgo","owner":"naughtygopher","description":"A microframework to build web apps; with handler chaining, middleware support, and most of all; standard library compliant HTTP handlers(i.e. http.HandlerFunc).","archived":false,"fork":false,"pushed_at":"2025-01-25T09:53:46.000Z","size":435,"stargazers_count":304,"open_issues_count":2,"forks_count":31,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-14T06:18:45.478Z","etag":null,"topics":["api-rest","api-server","awesome-go","awesome-golang","awesome-list","go","golang","golang-library","golang-module","golang-server","microframework","middleware","multiplexer","router","server-sent-events","web-framework","webframework","webgo"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/naughtygopher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-16T07:35:02.000Z","updated_at":"2025-03-20T01:28:27.000Z","dependencies_parsed_at":"2025-02-24T03:10:29.224Z","dependency_job_id":"da3c349a-6398-4867-96cd-340f1c33ed81","html_url":"https://github.com/naughtygopher/webgo","commit_stats":{"total_commits":246,"total_committers":8,"mean_commits":30.75,"dds":0.2845528455284553,"last_synced_commit":"1c8578aabe56fa486145fbdbba5ccee69d0298e6"},"previous_names":["naughtygopher/webgo","bnkamalesh/webgo"],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naughtygopher%2Fwebgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naughtygopher%2Fwebgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naughtygopher%2Fwebgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naughtygopher%2Fwebgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/naughtygopher","download_url":"https://codeload.github.com/naughtygopher/webgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254527071,"owners_count":22085917,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","api-server","awesome-go","awesome-golang","awesome-list","go","golang","golang-library","golang-module","golang-server","microframework","middleware","multiplexer","router","server-sent-events","web-framework","webframework","webgo"],"created_at":"2024-10-09T00:02:22.579Z","updated_at":"2025-05-16T12:00:19.220Z","avatar_url":"https://github.com/naughtygopher.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/1092882/60883564-20142380-a268-11e9-988a-d98fb639adc6.png\" alt=\"webgo gopher\" width=\"256px\"/\u003e\u003c/p\u003e\n\n[![](https://github.com/naughtygopher/webgo/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/naughtygopher/webgo/actions)\n[![Go Reference](https://pkg.go.dev/badge/github.com/naughtygopher/webgo.svg)](https://pkg.go.dev/github.com/naughtygopher/webgo)\n[![Go Report Card](https://goreportcard.com/badge/github.com/naughtygopher/webgo)](https://goreportcard.com/report/github.com/naughtygopher/webgo)\n[![Coverage Status](https://coveralls.io/repos/github/naughtygopher/webgo/badge.svg?branch=master)](https://coveralls.io/github/naughtygopher/webgo?branch=master)\n[![](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#web-frameworks)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/creativecreature/sturdyc/blob/master/LICENSE)\n\n# WebGo v7.0.4\n\nWebGo is a minimalistic router for [Go](https://golang.org) to build web applications (server side) with no 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc).\n\n### Contents\n\n1. [Router](https://github.com/naughtygopher/webgo#router)\n2. [Handler chaining](https://github.com/naughtygopher/webgo#handler-chaining)\n3. [Middleware](https://github.com/naughtygopher/webgo#middleware)\n4. [Error handling](https://github.com/naughtygopher/webgo#error-handling)\n5. [Helper functions](https://github.com/naughtygopher/webgo#helper-functions)\n6. [HTTPS ready](https://github.com/naughtygopher/webgo#https-ready)\n7. [Graceful shutdown](https://github.com/naughtygopher/webgo#graceful-shutdown)\n8. [Logging](https://github.com/naughtygopher/webgo#logging)\n9. [Server-Sent Events](https://github.com/naughtygopher/webgo#server-sent-events)\n10. [Usage](https://github.com/naughtygopher/webgo#usage)\n\n## Router\n\nWebgo has a simplistic, linear path matching router and supports defining [URI](https://developer.mozilla.org/en-US/docs/Glossary/URI)s with the following patterns\n\n1. `/api/users` - URI with no dynamic values\n2. `/api/users/:userID`\n   - URI with a named parameter, `userID`\n   - If TrailingSlash is set to true, it will accept the URI ending with a '/', refer to [sample](https://github.com/naughtygopher/webgo#sample)\n3. `/api/users/:misc*`\n   - Named URI parameter `misc`, with a wildcard suffix '\\*'\n   - This matches everything after `/api/users`. e.g. `/api/users/a/b/c/d`\n\nWhen there are multiple handlers matching the same URI, only the first occurring handler will handle the request.\nRefer to the [sample](https://github.com/naughtygopher/webgo#sample) to see how routes are configured. You can access named parameters of the URI using the `Context` function.\n\nNote: webgo Context is **not** available inside the special handlers (not found \u0026 method not implemented)\n\n```golang\nfunc helloWorld(w http.ResponseWriter, r *http.Request) {\n\t// WebGo context\n\twctx := webgo.Context(r)\n\t// URI paramaters, map[string]string\n\tparams := wctx.Params()\n\t// route, the webgo.Route which is executing this request\n\troute := wctx.Route\n\twebgo.R200(\n\t\tw,\n\t\tfmt.Sprintf(\n\t\t\t\"Route name: '%s', params: '%s'\",\n\t\t\troute.Name,\n\t\t\tparams,\n\t\t),\n\t)\n}\n```\n\n## Handler chaining\n\nHandler chaining lets you execute multiple handlers for a given route. Execution of a chain can be configured to run even after a handler has written a response to the HTTP request, if you set `FallThroughPostResponse` to `true` (refer [sample](https://github.com/naughtygopher/webgo/blob/master/cmd/main.go#L70)).\n\n## Middleware\n\nWebGo [middlware](https://godoc.org/github.com/naughtygopher/webgo#Middleware) lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method [Use](https://godoc.org/github.com/naughtygopher/webgo#Router.Use) \u0026\u0026 [UseOnSpecialHandlers](https://godoc.org/github.com/naughtygopher/webgo#Router.UseOnSpecialHandlers) to add a Middleware to the router.\n\nNotFound \u0026\u0026 NotImplemented are considered `Special` handlers. `webgo.Context(r)` within special handlers will return `nil`.\n\nAny number of middleware can be added to the router, the order of execution of middleware would be [LIFO](\u003chttps://en.wikipedia.org/wiki/Stack_(abstract_data_type)\u003e) (Last In First Out). i.e. in case of the following code\n\n```golang\nfunc main() {\n\trouter.Use(accesslog.AccessLog, cors.CORS(nil))\n\trouter.Use(\u003cmore middleware\u003e)\n}\n```\n\n**_CorsWrap_** would be executed first, followed by **_AccessLog_**.\n\n## Error handling\n\nWebgo context has 2 methods to [set](https://github.com/naughtygopher/webgo/blob/master/webgo.go#L60) \u0026 [get](https://github.com/naughtygopher/webgo/blob/master/webgo.go#L66) erro within a request context. It enables Webgo to implement a single middleware where you can handle error returned within an HTTP handler. [set error](https://github.com/naughtygopher/webgo/blob/master/cmd/main.go#L45), [get error](https://github.com/naughtygopher/webgo/blob/master/cmd/main.go#L51).\n\n## Helper functions\n\nWebGo provides a few helper functions. When using `Send` or `SendResponse` (other Rxxx responder functions), the response is wrapped in WebGo's [response struct](https://github.com/naughtygopher/webgo/blob/master/responses.go#L17) and is serialized as JSON.\n\n```json\n{\n  \"data\": \"\u003cany valid JSON payload\u003e\",\n  \"status\": \"\u003cHTTP status code, of type integer\u003e\"\n}\n```\n\nWhen using `SendError`, the response is wrapped in WebGo's [error response struct](https://github.com/naughtygopher/webgo/blob/master/responses.go#L23) and is serialzied as JSON.\n\n```json\n{\n  \"errors\": \"\u003cany valid JSON payload\u003e\",\n  \"status\": \"\u003cHTTP status code, of type integer\u003e\"\n}\n```\n\n## HTTPS ready\n\nHTTPS server can be started easily, by providing the key \u0026 cert file. You can also have both HTTP \u0026 HTTPS servers running side by side.\n\nStart HTTPS server\n\n```golang\ncfg := \u0026webgo.Config{\n\tPort: \"80\",\n\tHTTPSPort: \"443\",\n\tCertFile: \"/path/to/certfile\",\n\tKeyFile: \"/path/to/keyfile\",\n}\nrouter := webgo.NewRouter(cfg, routes()...)\nrouter.StartHTTPS()\n```\n\nStarting both HTTP \u0026 HTTPS server\n\n```golang\ncfg := \u0026webgo.Config{\n\tPort: \"80\",\n\tHTTPSPort: \"443\",\n\tCertFile: \"/path/to/certfile\",\n\tKeyFile: \"/path/to/keyfile\",\n}\n\nrouter := webgo.NewRouter(cfg, routes()...)\ngo router.StartHTTPS()\nrouter.Start()\n```\n\n## Graceful shutdown\n\nGraceful shutdown lets you shutdown the server without affecting any live connections/clients connected to the server. Any new connection request after initiating a shutdown would be ignored.\n\nSample code to show how to use shutdown\n\n```golang\nfunc main() {\n\tosSig := make(chan os.Signal, 5)\n\n\tcfg := \u0026webgo.Config{\n\t\tHost:            \"\",\n\t\tPort:            \"8080\",\n\t\tReadTimeout:     15 * time.Second,\n\t\tWriteTimeout:    60 * time.Second,\n\t\tShutdownTimeout: 15 * time.Second,\n\t}\n\trouter := webgo.NewRouter(cfg, routes()...)\n\n\tgo func() {\n\t\t\u003c-osSig\n\t\t// Initiate HTTP server shutdown\n\t\terr := router.Shutdown()\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\tos.Exit(1)\n\t\t} else {\n\t\t\tfmt.Println(\"shutdown complete\")\n\t\t\tos.Exit(0)\n\t\t}\n\n\t\t// If you have HTTPS server running, you can use the following code\n\t\t// err := router.ShutdownHTTPS()\n\t\t// if err != nil {\n\t\t// \tfmt.Println(err)\n\t\t// \tos.Exit(1)\n\t\t// } else {\n\t\t// \tfmt.Println(\"shutdown complete\")\n\t\t// \tos.Exit(0)\n\t\t// }\n\t}()\n\n\tgo func(){\n\t\ttime.Sleep(time.Second*15)\n\t\tsignal.Notify(osSig, os.Interrupt, syscall.SIGTERM)\n\t}()\n\n\trouter.Start()\n}\n```\n\n## Logging\n\nWebGo exposes a singleton \u0026 global scoped logger variable [LOGHANDLER](https://godoc.org/github.com/naughtygopher/webgo#Logger) with which you can plug in your custom logger by implementing the [Logger](https://godoc.org/github.com/naughtygopher/webgo#Logger) interface.\n\n### Configuring the default Logger\n\nThe default logger uses Go standard library's `log.Logger` with `os.Stdout` (for debug and info logs) \u0026 `os.Stderr` (for warning, error, fatal) as default io.Writers. You can set the io.Writer as well as disable specific types of logs using the `GlobalLoggerConfig(stdout, stderr, cfgs...)` function.\n\n## Server-Sent Events\n\n[MDN has a very good documentation of what SSE (Server-Sent Events)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) are. The sample app provided shows how to use the SSE extension of webgo.\n\n## Usage\n\nA fully functional sample is provided [here](https://github.com/naughtygopher/webgo/blob/master/cmd/main.go).\n\n### Benchmark\n\n1. [the-benchmarker](https://github.com/the-benchmarker/web-frameworks)\n2. [go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark)\n\n### Contributing\n\nRefer [here](https://github.com/naughtygopher/webgo/blob/master/CONTRIBUTING.md) to find out details about making a contribution\n\n### Credits\n\nThanks to all the [contributors](https://github.com/naughtygopher/webgo/graphs/contributors)\n\n## The gopher\n\nThe gopher used here was created using [Gopherize.me](https://gopherize.me/). WebGo stays out of developers' way, so sitback and enjoy a cup of coffee.\n","funding_links":[],"categories":["Web Frameworks","Integrating Open telemetry for instrumentation","How to use?","Web框架"],"sub_categories":["Utility/Miscellaneous","internal/server/http/web/templates","实用程序/Miscellaneous"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaughtygopher%2Fwebgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnaughtygopher%2Fwebgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaughtygopher%2Fwebgo/lists"}