{"id":15331312,"url":"https://github.com/flimzy/hapi","last_synced_at":"2026-05-13T09:31:31.307Z","repository":{"id":34470659,"uuid":"38407773","full_name":"flimzy/hapi","owner":"flimzy","description":"Hypermedia API router and minimal framework for Go","archived":false,"fork":false,"pushed_at":"2015-08-09T19:05:20.000Z","size":220,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-02T05:44:24.672Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/flimzy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-02T02:56:23.000Z","updated_at":"2019-03-20T14:16:21.000Z","dependencies_parsed_at":"2022-08-03T21:00:11.503Z","dependency_job_id":null,"html_url":"https://github.com/flimzy/hapi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flimzy%2Fhapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flimzy%2Fhapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flimzy%2Fhapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flimzy%2Fhapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flimzy","download_url":"https://codeload.github.com/flimzy/hapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241476458,"owners_count":19968916,"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":[],"created_at":"2024-10-01T09:55:15.429Z","updated_at":"2026-05-13T09:31:26.283Z","avatar_url":"https://github.com/flimzy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/flimzy/hapi.svg?branch=master)](https://travis-ci.org/flimzy/hapi)\n\n# What is HAPI?\n\nHAPI, short for **Hypermedia API**, is an HTTP router/mux for creating Hypermedia APIs (aka REST) for the Go language.\nIt is built on top of and extends [httprouter](https://github.com/julienschmidt/httprouter).\n\n# Design goals\n\nMy primary design goal is to extend the traditional HTTP router to also handle multiple content types easily.\n\nMost web frameworks and HTTP routers (upon which frameworks are often written) tend to focus on a single dimension of the HTTP request:\nThe URL.\n\nAn example from [gorilla mux](http://www.gorillatoolkit.org/pkg/mux):\n\n    func main() {\n        r := mux.NewRouter()\n        r.HandleFunc(\"/\", HomeHandler)\n        r.HandleFunc(\"/products\", ProductsHandler)\n        r.HandleFunc(\"/articles\", ArticlesHandler)\n        http.Handle(\"/\", r)\n    }\n\nFor simple web sites, this can be enough (or nearly enough).  But in recent times, many routers have started to emphasise a second essential\ndimension of the HTTP request: The HTTP method.\n\nAn example from [httprouter](https://github.com/julienschmidt/httprouter#web-frameworks-based-on-httprouter):\n\n    func main() {\n        // Initialize a router as usual\n        router := httprouter.New()\n        router.GET(\"/\", Index)\n        router.GET(\"/hello/:name\", Hello)\n        \nThis is obviously a big improvement for authors of REST APIs.  But it is my opinion that this doesn't go far enough if you want to fully leverage\na Hypermedia API. The missing dimension is the media type.\n\nWhenever your httprouter ignores a dimension you care about, you end up doing your own \"routing\" inside of your handler function. To handle GET and POST differently with gorilla/mux, for instance, you must check the request method within your handler, then call the appropriate function yourself.\n\nSimilarly, if you have one function that produces an HTML representation of a resource, and another that produces a PDF, your own handler must determine which media type is requested (by parsing the Accept: header in the request), then doing your own internal routing yourself.\n\nBy handling this in the router, it also makes it easier to provide a 406 error in the case that the client requests a type you can't provide, even if you only provide a single media type in your API.\n\nWe have similar problems if we need to consume requests with bodies of different media types. Perhaps you want to accept input from your clients as either JSON+Collection or as XML. You have to do all that bookkeeping and piping yourself.\n\nThus the primary goal of HAPI is to simplify the media type dimension of Hypermedia API routing.\n\n## Compatibility\n\nHAPI is essentially a wrapper around [httprouter](https://github.com/julienschmidt/httprouter#web-frameworks-based-on-httprouter), and like httprouter, it provides a couple of functions to make it easy to use http.Handler, http.HandlerFunc: hapi.Handler(), and hapi.HandlerFunc() respectively.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflimzy%2Fhapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflimzy%2Fhapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflimzy%2Fhapi/lists"}