{"id":25709173,"url":"https://github.com/manigandand/adk","last_synced_at":"2025-04-30T16:43:53.506Z","repository":{"id":59047244,"uuid":"533903817","full_name":"manigandand/adk","owner":"manigandand","description":"Golang API Development Kit ","archived":false,"fork":false,"pushed_at":"2023-10-05T08:25:07.000Z","size":56,"stargazers_count":15,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T17:51:14.898Z","etag":null,"topics":["api","api-rest","go-chi","golang","golang-library","gorrila"],"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/manigandand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2022-09-07T19:06:41.000Z","updated_at":"2023-08-23T16:34:50.000Z","dependencies_parsed_at":"2023-01-31T11:30:24.001Z","dependency_job_id":null,"html_url":"https://github.com/manigandand/adk","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manigandand%2Fadk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manigandand%2Fadk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manigandand%2Fadk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manigandand%2Fadk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manigandand","download_url":"https://codeload.github.com/manigandand/adk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251747002,"owners_count":21637351,"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","api-rest","go-chi","golang","golang-library","gorrila"],"created_at":"2025-02-25T09:22:39.328Z","updated_at":"2025-04-30T16:43:53.479Z","avatar_url":"https://github.com/manigandand.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## ADK - Golang API Development Kit\n\n[![CircleCI](https://circleci.com/gh/manigandand/adk/tree/master.svg?style=shield)](https://circleci.com/gh/manigandand/adk/tree/master)\n[![Go Report](https://goreportcard.com/badge/github.com/manigandand/adk)](https://goreportcard.com/report/github.com/manigandand/adk)\n[![GolangCI](https://golangci.com/badges/github.com/manigandand/adk.svg)](https://golangci.com/r/github.com/manigandand/adk)\n[![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://github.com/manigandand/adk/blob/master/LICENSE)\n[![](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/manigandand/adk)\n\n**GoDoc Reference:**\n- api: [![](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/manigandand/adk/api)\n- errors: [![](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/manigandand/adk/errors)\n- respond: [![](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/manigandand/adk/respond)\n\n---\n\n[![GOPHERCON 2022 | ADK - Golang API Development Kit](https://img.youtube.com/vi/opReKsCXsA0/0.jpg)](https://www.youtube.com/watch?v=opReKsCXsA0)\n\n---\n\nCommon utilities to write simple apis in golang.\n\n```shell\n- Custom API Handlers\n  - Custom API Request(JSON) Decoders\n  - Custom API URL Query-params Decoders using gorrila schema.\n- App Errors\n- Response Writers\n```\n\n\u003e Ex: **Conventional way of writing api**\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/go-chi/chi/v5/middleware\"\n)\n\nfunc main() {\n\tr := chi.NewRouter()\n\tr.Use(middleware.Logger)\n\tr.Post(\"/user\", CreateUserHandler)\n\thttp.ListenAndServe(\":3000\", r)\n}\n\n// CreateUserHandler creates a new users\nfunc CreateUserHandler(w http.ResponseWriter, r *http.Request) {\n    ctx := r.Context()\n\n\treqBts, err := ioutil.ReadAll(r.Body)\n\tif err != nil {\n        w.Header().Add(\"Content-Type\", \"application/json\")\n\t\tw.WriteHeader(http.StatusBadRequest)\n        w.Write([]byte(`{\"error\": \"Couldn't read request body\"}`))\n\t\treturn\n\t}\n\n\tvar createReq createUserReq\n\tjErr := json.Unmarshal(reqBts, \u0026createReq)\n\tif jErr != nil {\n        w.Header().Add(\"Content-Type\", \"application/json\")\n\t\tw.WriteHeader(http.StatusBadRequest)\n        w.Write([]byte(`{\"error\": \"invalid request body\"}`))\n\t\treturn\n\t}\n    if err := validateCreateUserReq(\u0026createReq); err != nil {\n        w.Header().Add(\"Content-Type\", \"application/json\")\n\t\tw.WriteHeader(http.StatusBadRequest)\n        w.Write([]byte(`{\"error\": \"invalid request body\"}`))\n\t\treturn\n    }\n    if err := store.CreateUser(\u0026createReq); err != nil {\n        w.Header().Add(\"Content-Type\", \"application/json\")\n\t\tw.WriteHeader(http.StatusInternalServerError)\n        w.Write([]byte(`{\"error\": \"invalid request body\"}`))\n\t\treturn\n    }\n\n    // respond to the client\n    w.Header().Add(\"Content-Type\", \"application/json\")\n    w.WriteHeader(http.StatusOK)\n    w.Write([]byte(`{\"message\": \"user created successfully\", \"id\": 123}`))\n}\n```\n\n### After using custom handlers and ADK\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n    \"github.com/manigandand/adk/api\"\n    \"github.com/manigandand/adk/errors\"\n    \"github.com/manigandand/adk/middleware\"\n    \"github.com/manigandand/adk/respond\"\n\n\t\"github.com/go-chi/chi/v5\"\n)\n\nfunc main() {\n\tr := chi.NewRouter()\n\tr.Use(middleware.Logger)\n    r.Use(middleware.Recoverer)\n\n\tr.Method(http.MethodPost, \"/user\", api.Handler(CreateUserHandler))\n\thttp.ListenAndServe(\":3000\", r)\n}\n\ntype createUserReq struct {\n    Email string `json:\"email\"`\n    Name  string `json:\"name\"`\n}\n\nfunc (c *createUserReq) Validate() *errors.AppError {\n    if c.Email == \"\" {\n        return errors.KeyRequired(\"email\")\n    }\n    return nil\n}\n\n// CreateUserHandler creates a new users\nfunc CreateUserHandler(w http.ResponseWriter, r *http.Request) *errors.AppError{\n    ctx := r.Context()\n\n\tvar createReq createUserReq\n\n\tif err := api.Decode(r, \u0026createReq); err != nil {\n\t\treturn err\n\t}\n    if err := store.CreateUser(\u0026createReq); err != nil {\n\t\treturn err\n    }\n\n    // respond to the client\n    return respond.OK(w, map[string]interface{}{\n        \"message\": \"user created successfully\",\n        \"id\": 123,\n    })\n}\n```\n\n\u003e NOTE:\n\u003e Decoder currently will work on only on the `\"application/json\"` body.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanigandand%2Fadk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanigandand%2Fadk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanigandand%2Fadk/lists"}