{"id":16092330,"url":"https://github.com/alecthomas/pathways","last_synced_at":"2025-04-05T18:47:21.343Z","repository":{"id":8876617,"uuid":"10592105","full_name":"alecthomas/pathways","owner":"alecthomas","description":"Pathways - An opinionated RESTful web service framework for Go","archived":false,"fork":false,"pushed_at":"2024-02-01T08:47:21.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-18T17:06:53.883Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2013-06-10T02:06:03.000Z","updated_at":"2013-10-03T02:05:01.000Z","dependencies_parsed_at":"2024-10-31T10:22:47.833Z","dependency_job_id":"ec967c5b-81a9-4ef6-94b6-72e3c9f3f789","html_url":"https://github.com/alecthomas/pathways","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/alecthomas%2Fpathways","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fpathways/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fpathways/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fpathways/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/pathways/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247385703,"owners_count":20930600,"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-09T16:07:06.202Z","updated_at":"2025-04-05T18:47:21.268Z","avatar_url":"https://github.com/alecthomas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pathways - a RESTful web service framework for Go\n\nThe goal of Pathways is to make building RESTful web services simple.\n\nPathways centers around the concept of services. Services define exactly how every endpoint in a web service is accessed and handled. This provides several benefits, including the ability to construct client requests, and the ability to autogenerate API documentation.\n\n## Example\n\nHere's an example of an in-memory key-value service and client with Pathways:\n\n```go\npackage main\n\nimport (\n    \"github.com/alecthomas/pathways\"\n    \"net/http\"\n)\n\ntype KeyValueService struct {\n    service *pathways.Service\n    kv      map[string]string\n}\n\nfunc KeyValueServiceMap(root string) *pathways.Service {\n    s := pathways.NewService(root)\n    s.Path(\"/\").Name(\"List\").Get().APIResponseType(map[string]string{})\n    str := \"\"\n    s.Path(\"/{key}\").Name(\"Get\").Get().APIResponseType(\u0026str)\n    s.Path(\"/{key}\").Name(\"Create\").Post().APIRequestType(\u0026str)\n    s.Path(\"/{key}\").Name(\"Delete\").Delete()\n    return s\n}\n\nfunc NewClient(url string) *pathways.Client {\n    s := KeyValueServiceMap(url)\n    return pathways.NewClient(s, \"application/json\")\n}\n\nfunc NewKeyValueService(root string) *KeyValueService {\n    k := \u0026KeyValueService{\n        service: KeyValueServiceMap(root),\n        kv:      make(map[string]string),\n    }\n    k.service.Find(\"List\").APIFunction(k.List)\n    k.service.Find(\"Get\").APIFunction(k.Get)\n    k.service.Find(\"Create\").APIFunction(k.Create)\n    k.service.Find(\"Delete\").APIFunction(k.Delete)\n    return k\n}\n\nfunc (k *KeyValueService) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n    k.service.ServeHTTP(w, r)\n}\n\nfunc (k *KeyValueService) List(cx *pathways.Context) pathways.Response {\n    return cx.APIResponse(http.StatusOK, k.kv)\n}\n\nfunc (k *KeyValueService) Get(cx *pathways.Context) pathways.Response {\n    return cx.APIResponse(http.StatusOK, k.kv[cx.PathVars[\"key\"]])\n}\n\nfunc (k *KeyValueService) Create(cx *pathways.Context, value *string) pathways.Response {\n    k.kv[cx.PathVars[\"key\"]] = *value\n    return cx.APIResponse(http.StatusCreated, \"ok\")\n}\n\nfunc (k *KeyValueService) Delete(cx *pathways.Context) pathways.Response {\n    delete(k.kv, cx.PathVars[\"key\"])\n    return cx.APIResponse(http.StatusOK, \u0026struct{}{})\n}\n\nfunc main() {\n    s := NewKeyValueService(\"/api/\")\n    http.ListenAndServe(\":8080\", s)\n}\n```\n\nTest with:\n\n```bash\n$ curl http://localhost:8080/api/\n{}\n$ curl --data-binary '\"hello world\"' http://localhost:8080/api/foo\n\"ok\"\n$ curl http://localhost:8080/api/\n{\"foo\":\"hello world\"}\n$ curl http://localhost:8080/api/foo\n\"hello world\"\n```\n## Features\n\n### A simple yet flexible URL routing engine\n\nFor example, the following service definition might specify routes for a key/value store:\n\n```go\ns := pathways.NewService(\"/kv/\")\ns.Path(\"/\").Name(\"List\").Get()\ns.Path(\"/{key}\").Name(\"Create\").Post()\ns.Path(\"/{key}\").Name(\"Get\").Get()\ns.Path(\"/{key}\").Name(\"Delete\").Delete()\n```\n\n### Automatic serialization/deserialization of requests/responses\n\nPathways routes can define the request and response structures expected, and route directly to functions and methods, passing the deserialized request as an argument:\n\n```go\ntype KeyValueService struct {\n}\n\nfunc (k *KeyValueService) Create(cx *pathways.Context, req *CreateRequest) pathways.Response {\n    // ... do something with deserialized request\n    return cx.APIResponse(http.StatusOK, \u0026CreateResponse{})\n}\n\nkvs := \u0026KeyValueService{}\n\ns.Path(\"/{key}\").Name(\"Create\").Post().APIRequestType(\u0026CreateRequest{}).APIResponseType(\u0026CreateResponse{}).APIFunction(kvs.Create)\n```\n\n### RESTful client using the service definition\n\nThe following will issue a `GET` request to `/kv/key` with the request body from `CreateRequest`. The response will be returned as a `CreateResponse` structure:\n\n```go\nc := pathways.NewClient(s, \"application/x-msgpack\")\nresponse := \u0026CreateResponse{}\nerr := c.Call(\"Create\", pathways.Args{\"key\": \"somekey\"}, \u0026CreateRequest{...}, response)\n```\n\n### Transparent support for JSON, MsgPack and BSON serialized requests/responses\n\nThe content-types for these formats are `application/json`, `application/x-msgpack` and `application/bson`. Setting the request `Content-Type` and/or `Accept` headers to one of these will set the desired serialization format. The default is JSON.\n\nThe Pathways server will detect the correct serialization format from request headers (falling back on JSON). The Pathways client will use the serialization format specified in the constructor.\n\nWhy not support only JSON? Primarily because JSON has [limitations on the numeric values](http://cdivilly.wordpress.com/2012/04/11/json-javascript-large-64-bit-integers/) that can be represented.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fpathways","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Fpathways","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fpathways/lists"}