{"id":16728340,"url":"https://github.com/tmc/glue","last_synced_at":"2025-10-15T05:44:02.250Z","repository":{"id":13603280,"uuid":"16296224","full_name":"tmc/glue","owner":"tmc","description":"Small HTTP library for Go. Less than 250 LOC","archived":false,"fork":false,"pushed_at":"2014-02-03T01:11:15.000Z","size":272,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-05T18:11:08.686Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"godoc.org/github.com/tmc/glue","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tmc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-27T23:12:31.000Z","updated_at":"2022-11-28T16:17:19.000Z","dependencies_parsed_at":"2022-08-31T08:41:21.698Z","dependency_job_id":null,"html_url":"https://github.com/tmc/glue","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tmc/glue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmc%2Fglue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmc%2Fglue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmc%2Fglue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmc%2Fglue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tmc","download_url":"https://codeload.github.com/tmc/glue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmc%2Fglue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278557633,"owners_count":26006355,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-10-12T23:09:57.391Z","updated_at":"2025-10-06T04:25:33.311Z","avatar_url":"https://github.com/tmc.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# glue\n    import \"github.com/tmc/glue\"\n\n[![Build Status](https://drone.io/github.com/tmc/glue/status.png)](https://drone.io/github.com/tmc/glue/latest)\n\nPackage glue provides a simple interface to writing HTTP services in Go\n\nIt aims to be small and as simple as possible while exposing a pleasant API.\n\nGlue uses reflection and dependency injection to provide a flexible API for your\nHTTP endpoints. There is an obvious tradeoff here. The cost of this flexibility\nis some static safety and some performance overhead (though this appears\nnegligible in benchmarking).\n\nContributions welcome!\n\n- godoc: http://godoc.org/github.com/tmc/glue\n- license: ISC\n- status: *api-instable!*\n\nFeatures\n\n\t* small (~250LOC)\n\t* compatible with the net/http Handler and HandleFunc interfaces.\n\t* provides mechanism for before and after request middleware\n\n\nBasic Example:\n\n\n```go\npackage main\nimport \"github.com/tmc/glue\"\n\nfunc main() {\n    g := glue.New()\n    g.Get(\"/\", func() string {\n        return \"hello world\"\n    })\n    g.Listen() // listens on :5000 by default (uses PORT environtment variable)\n}\n```\n\nExample showing middleware, logging, routing, and static file serving:\n\n```go\ng := glue.New()\n// Register a new type with the underlying DI container\ng.Register(log.New(os.Stderr, \"[glue example] \", log.LstdFlags))\n// Add a new glue.Handler that will be invoked for each request\ng.AddHandler(loggers.NewApacheLogger())\n// Add a handler using routing and parameter capture\ng.Get(\"/{type}_teapot\", func(r *http.Request) (int, string) {\n    return http.StatusTeapot, \"that is \" + r.URL.Query().Get(\":type\") + \"!\"\n})\n// Serve static files\ng.Get(\"/\", http.FileServer(http.Dir(\"./static/\")))\ngo g.Listen() // listens on 5000 by default (uses PORT environtment variable)\n\nresp, err := http.Get(\"http://127.0.0.1:5000/purple_teapot\")\nif err != nil {\n    panic(err)\n}\ndefer resp.Body.Close()\nbody, err := ioutil.ReadAll(resp.Body)\nfmt.Println(resp.Status, string(body))\n// Output:\n// 418 I'm a teapot that is purple!\n```\n\n\n## type AfterHandler\n```go\ntype AfterHandler func(Context)\n```\nAfterHandler is a type that a glue Handler can return and have it invoked\nafter the default handler. This allows middleware to execute logic after a\nresponse has started. See github.com/tmc/glue/loggers for an example.\n\n\n\n## type Context\n``` go\ntype Context struct {\n    inj.Injector\n    // contains filtered or unexported fields\n}\n```\nContext represents the execution context for a request in Glue\nIt is a DI (Dependency Injection) container and contains an augmented\nResponseWriter\n\n\n\n## type Glue\n``` go\ntype Glue struct {\n    inj.Injector\n    // contains filtered or unexported fields\n}\n```\nGlue is the primary struct that exposes routing and Handler registration\n\n\n### func New\n``` go\nfunc New() *Glue\n```\nNew prepares a new Glue instance and registers the default ResponseHandler\n\n\n### func (\\*Glue) Add\n``` go\nfunc (g *Glue) Add(handler Handler)\n```\nAdd adds a handler to the default set of handlers for a Glue instance\n\n\n### func (Glue) Delete\n``` go\nfunc (r Glue) Delete(pat string, h Handler) *mux.Route\n```\nDelete registers a pattern with a handler for DELETE requests.\n\n\n### func (Glue) Get\n``` go\nfunc (r Glue) Get(pat string, h Handler) *mux.Route\n```\nGet registers a pattern with a handler for GET requests.\n\n\n### func (Glue) Handle\n``` go\nfunc (r Glue) Handle(w http.ResponseWriter, req *http.Request, c Context)\n```\nHandle is a glue.Handler that does route matching and invokes the registered\nglue.Handler for a route.\n\nIf a route is not found the NotFoundHandler is invoked.\n\n\n### func (\\*Glue) Listen\n``` go\nfunc (g *Glue) Listen()\n```\nListen attempts to ListenAndServe based on the environment variables HOST and PORT\n\n\n### func (Glue) Post\n``` go\nfunc (r Glue) Post(pat string, h Handler) *mux.Route\n```\nPost registers a pattern with a handler for POST requests.\n\n\n### func (Glue) Put\n``` go\nfunc (r Glue) Put(pat string, h Handler) *mux.Route\n```\nPut registers a pattern with a handler for PUT requests.\n\n\n### func (\\*Glue) ServeHTTP\n``` go\nfunc (g *Glue) ServeHTTP(w http.ResponseWriter, r *http.Request)\n```\nServeHTTP satisfies the http.Handler interface\n\n\n## type Handler\n``` go\ntype Handler interface{}\n```\nHandler is a generic type that must be a callable function.\n\nIt is invoked with the Call method of inj.Injector (http://godoc.org/github.com/tmc/inj#Injector.Call) which provides DI\n(Dependency Injection) based on the types of arguments it accepts.\n\nAccepting a glue.Context allows you to inspect the DI container and examine\nthe currently registered types.\n\nThe default registered ResponseHandler expects Handlers to return either one or two values.\n\nIf one value, it should return a string or a byte slice.\nIf two values, the first should be an int which will be used as the return code.\n\n\n\n## type ResponseHandler\n``` go\ntype ResponseHandler func(http.ResponseWriter, []reflect.Value)\n```\nResponseHandler is a type that writes an HTTP response given a slice of reflect.Value\n\n## type ResponseWriter\n``` go\ntype ResponseWriter struct {\n    http.ResponseWriter\n    Size   int // the number of bytes that have been written as a response body\n    Status int // the status code that has been written to the response (or zero if unwritten)\n}\n```\nResponseWriter is an augmented http.ResponseWriter that exposes some additional fields\n\n\n### func (\\*ResponseWriter) Write\n``` go\nfunc (rw *ResponseWriter) Write(b []byte) (int, error)\n```\nWrite writes the data to the connection as part of an HTTP reply.\nIf WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)\nbefore writing the data.  If the Header does not contain a\nContent-Type line, Write adds a Content-Type set to the result of passing\nthe initial 512 bytes of written data to DetectContentType.\n\n\n\n### func (\\*ResponseWriter) WriteHeader\n``` go\nfunc (rw *ResponseWriter) WriteHeader(status int)\n```\nWriteHeader sends an HTTP response header with status code.\nIf WriteHeader is not called explicitly, the first call to Write\nwill trigger an implicit WriteHeader(http.StatusOK).\nThus explicit calls to WriteHeader are mainly used to\nsend error codes.\n\n\n\n### func (\\*ResponseWriter) WroteHeader\n``` go\nfunc (rw *ResponseWriter) WroteHeader() bool\n```\nWroteHeader indicates if a header has been written (and a response has been started)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmc%2Fglue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftmc%2Fglue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmc%2Fglue/lists"}