{"id":21296888,"url":"https://github.com/reddec/rpc","last_synced_at":"2025-07-11T18:32:05.795Z","repository":{"id":41807660,"uuid":"510373936","full_name":"reddec/rpc","owner":"reddec","description":"Golang and JS interaction made simple","archived":false,"fork":false,"pushed_at":"2023-06-19T08:40:09.000Z","size":41,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-02T11:02:03.129Z","etag":null,"topics":["golang-json-api","golang-rpc","rpc"],"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/reddec.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-04T13:38:27.000Z","updated_at":"2025-05-30T21:27:29.000Z","dependencies_parsed_at":"2024-06-20T00:13:52.966Z","dependency_job_id":"e1730e19-3c7e-4cd8-b21d-0e4a41bafa9f","html_url":"https://github.com/reddec/rpc","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/reddec/rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Frpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Frpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Frpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Frpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reddec","download_url":"https://codeload.github.com/reddec/rpc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Frpc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264870434,"owners_count":23676226,"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":["golang-json-api","golang-rpc","rpc"],"created_at":"2024-11-21T14:30:23.629Z","updated_at":"2025-07-11T18:32:05.404Z","avatar_url":"https://github.com/reddec.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RPC\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/reddec/rpc.svg)](https://pkg.go.dev/github.com/reddec/rpc)\n\n\u003e Calling Golang backend should be simple.\n\n- no runtime dependencies (for TS generator there is a compile-time dependency)\n- 100% test coverage\n- simple and efficient\n\nThis project was created within one night after my frustration while writing yet another service which basically exposes\nDB operations as an HTTP endpoint. The problem is that most of the current approaches offer some kind of framework lock.\nOnce you write your business logic, you will, basically, have to duplicate the method, which will just accept values\nfrom an HTTP request and proxy it to the business function.\n\nThis project allows you to expose almost any kind of structure method as HTTP endpoints.\n\nSupports:\n\n- Any input and output arguments as soon as it is supported by JSON encoder/decoder\n    - (optionally) First argument can be `context.Context` and it will be wired to `request.Context()`\n- Value and/or error output. Example:\n    - `Foo(...)`\n    - `Foo(...) error`\n    - `Foo(...) int64`\n    - `Foo(...) (int64, error)`\n\n\u003e There are two main packages: [`rpc`](https://pkg.go.dev/github.com/reddec/rpc) and [`jrpc`](https://pkg.go.dev/github.com/reddec/rpc/jrpc).\n\u003e The  [`rpc`](https://pkg.go.dev/github.com/reddec/rpc) is array-based interaction (function arguments are mapped as-is as array),\n\u003e and [`jrpc`](https://pkg.go.dev/github.com/reddec/rpc/jrpc) package is single-payload oriented.\n\u003e\n\u003e [`rpc`](https://pkg.go.dev/github.com/reddec/rpc) provides less restrictions for Go side, while [`jrpc`](https://pkg.go.dev/github.com/reddec/rpc/jrpc) more friendly for UI and code-generators.\n\nSimplest possible example:\n\n```go\npackage main\n\ntype Service struct{}\n\nfunc (srv *Service) Sum(a, b int64) int64 {\n\treturn a + b\n}\n\nfunc main() {\n\thttp.Handle(\"/api/\", http.StripPrefix(\"/api\", rpc.New(\u0026Service{})))\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n```\n\nIn JS side (you can just copy-and-paste)\n\n```js\nfunction RPC(baseURL = \"\") {\n    return new Proxy({}, {\n        get(obj, method) {\n            method = method.toLowerCase();\n            if (method in obj) {\n                return obj[method]\n            }\n\n            const url = baseURL + \"/\" + encodeURIComponent(method)\n            const fn = async function () {\n                const args = Array.prototype.slice.call(arguments);\n                const res = await fetch(url, {\n                    method: \"POST\",\n                    body: JSON.stringify(args),\n                    headers: {\n                        \"Content-Type\": \"application/json\"\n                    }\n                })\n                if (!res.ok) {\n                    const errMessage = await res.text();\n                    throw new Error(errMessage);\n                }\n                return await res.json()\n            }\n            return obj[method] = fn\n        }\n    })\n}\n```\n\nAnd use it as:\n\n```js\nconst api = RPC(\"/api\");\n\nconst amount = await api.sum(123, 456)\n```\n\n**Alternative** is to use CDN (seriously? for 375 bytes?)\n\n```html\n\n\u003cscript type=\"module\"\u003e\n    import RPC from \"https://cdn.jsdelivr.net/gh/reddec/rpc@1/js/rpc.min.js\"\n\n    const API = RPC(\"/api\");\n    const total = await API.sum(123, 456);\n\u003c/script\u003e\n```\n\n## Dynamic session\n\nIn some cases you may need to prepare session, based on request: find user, authenticate it and so on. For that\nuse `Builder`.\n\n`Builder` will invoke factory on each request and use returned value as API session object.\n\nFor example:\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\t\"github.com/reddec/rpc\"\n)\n\ntype userSession struct {\n\tuser string\n}\n\nfunc (us *userSession) Greet() string { // this will be an exported method\n\treturn \"Hello, \" + us.user + \"!\"\n}\n\ntype server struct{}\n\nfunc (srv *server) newSession(r *http.Request) (*userSession, error) {\n\tuser := r.Header.Get(\"X-User\") // mimic real authorization\n\treturn \u0026userSession{\n\t\tuser: user,\n\t}, nil\n}\n\nfunc main() {\n\tvar srv server // initialize it!\n\thttp.Handle(\"/api/\", http.StripPrefix(\"/api\", rpc.Builder(srv.newSession)))\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n```\n\nNow, on call `api.greet()`, first will be executed `newSession` and then `userSession.Greet`\n\n### Supporting tools\n\n#### RPC script\n\nMinified version of js/rpc.js supporting script (~400B) embedded to the library and available as global variable\n`rpc.JS` and can be exposed as handler by `Script` function:\n\n```go\n// ...\nhttp.Handle(\"/static/js/rpc.min.js\", rpc.Script())\n```\n\n#### Schema\n\nPackage `schema` provides simple way to generate OpenAPI 3.1 schema based on indexed methods from server.\nThe generated object could be serialized as YAML or JSON and served as handler.\n\nThe function `schema.OpenAPI` uses result of `Index` function to generate schema and definition.\n\n```go\nvar srv Server\nindex := rpc.Index(\u0026srv)\nschema := schema.OpenAPI(index) // customizable by Options\n// render as JSON or YAML\n```\n\nFor the convenience use handler to export schema over HTTP. It will pre-generate and cache schema.\n\n```go\nvar srv Server\nindex := rpc.Index(\u0026srv)\n// ...\nhttp.Handle(\"/schema\", schema.Handler(index))\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freddec%2Frpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freddec%2Frpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freddec%2Frpc/lists"}