{"id":21401947,"url":"https://github.com/bigjk/nra","last_synced_at":"2025-03-16T16:20:38.649Z","repository":{"id":57513463,"uuid":"191932748","full_name":"BigJk/nra","owner":"BigJk","description":"Minimal RPC library to call Go from Javascript","archived":false,"fork":false,"pushed_at":"2022-04-01T19:32:07.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-23T03:17:55.501Z","etag":null,"topics":["golang","javascript","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/BigJk.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":"2019-06-14T11:35:17.000Z","updated_at":"2022-04-01T19:28:49.000Z","dependencies_parsed_at":"2022-08-31T23:00:53.021Z","dependency_job_id":null,"html_url":"https://github.com/BigJk/nra","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigJk%2Fnra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigJk%2Fnra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigJk%2Fnra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigJk%2Fnra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BigJk","download_url":"https://codeload.github.com/BigJk/nra/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243894350,"owners_count":20365016,"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","javascript","rpc"],"created_at":"2024-11-22T15:33:45.995Z","updated_at":"2025-03-16T16:20:38.627Z","avatar_url":"https://github.com/BigJk.png","language":"Go","readme":"# nra\n[![Documentation](https://godoc.org/github.com/BigJk/nra?status.svg)](http://godoc.org/github.com/BigJk/nra) [![Go Report Card](https://goreportcard.com/badge/github.com/BigJk/nra)](https://goreportcard.com/report/github.com/BigJk/nra)\n\nnra (not REST again) is a minimal RPC library to call Go from Javascript. After building yet another REST api just to get some data from a Go backend to a small frontend I grew tired of the process. This library is not intended as a replacement for REST. It purpose is to get data from Go to Javascript with the smallest amount of work. It's perfect for small pet projects where you don't need any advanced features, high security or insane throughput.\n\n# Javascript Code\n\nThis code is all you need to call a function that is defined in your Go code. Just copy and paste it into your Javascript.\n\n```Javascript\nfunction call(func, ...args) {\n  return new Promise(function(resolve, reject) {\n    var request = new XMLHttpRequest();\n    request.open('POST', '/rpc/' + func, true);\n\n    request.onload = function() {\n      if (request.status === 200) {\n        resolve(JSON.parse(request.responseText));\n      } else {\n        reject(request.responseText);\n      }\n    };\n\n    request.onerror = function() {\n      reject(request.responseText);\n    };\n\n    request.send(JSON.stringify(args));\n  });\n}\n```\n\n### Minified\n\n```Javascript\nfunction call(e,...n){return new Promise(function(r,s){var t=new XMLHttpRequest;t.open(\"POST\",\"/rpc/\"+e,!0),t.onload=function(){200===t.status?r(JSON.parse(t.responseText)):s(t.responseText)},t.onerror=function(){s(t.responseText)},t.send(JSON.stringify(n))})}\n```\n\n# Example\n\nImagine you have a Go application that stores logs and you want to build a small Frontend that shows the last 100 logs that contain some search string.\n\n```Go\npackage main\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n\t\"fmt\"\n\n\t\"github.com/BigJk/nra\"\n)\n\nfunc main() {\n  // RPC functions should be prefixed\n  // with the '/rpc/' path when registering.\n  http.HandleFunc(\"/rpc/get_logs\", nra.MustBind(func(search string, limit int) ([]string, error) {\n    // lets generate some fake data here.\n    // normally some cool database access\n    // would happen here.\n    fakeLogs := make([]string, limit)\n    for i := 0; i \u003c limit; i++ {\n      fakeLogs[i] = fmt.Sprintf(\"%d. some data %s\", i, search)\n    }\n    return fakeLogs, nil\n  }))\n\n  // host your html, javascript etc.\n  http.Handle(\"/\", http.FileServer(http.Dir(\"static\")))\n\n  // start the server\n  http.ListenAndServe(\":8765\", nil)\n}\n```\n\nSomewhere in your Javascript\n\n```Javascript\ncall('get_logs', 'error', 100).then(function(logs) {\n  console.log(logs);\n}, function(err) {\n  console.log(err);\n})\n```\n\nThats it. You can bind any Go function as long as it returns 2 values. The first one can be of any type you like to return to your Javascript and the second one must be a error. Checking if the call from Javascript has the correct arguments and marshaling and unmarshaling the data will all be handled by nra.\n\n# Structs\n\nPassing structs from Javascript to Go and back is also supported.\n\n```Go\ntype Search struct {\n  Text   string `json:\"text\"`\n  Limit  int    `json:\"limit\"`\n}\n\ntype DataEntry struct {\n  Text   string    `json:\"text\"`\n  Time   time.Time `json:\"time\"`\n}\n\nhttp.HandleFunc(\"/rpc/get_structs\", nra.MustBind(func(search Search) ([]DataEntry, error) {\n  // search and return your DataEntries\n}))\n```\n\n```Javascript\ncall('get_logs', { text: \"my search\", limit: 250 }).then(function(data_entries) {\n  console.log(data_entries);\n}, function(err) {\n  console.log(err);\n})\n```\n\n# How does it work?\n\n#### Go\n\nFeel free to take a look at ``nra.go`` it's not even 200 lines of code and most of that are comments! To keep it short. nra looks at what arguments your function takes. When a request hits the generated handler function it will unmarshal the body of the request (which will contain the arguments that have been passed to the Javascript ``call`` function) and checks if the arguments and their type match your function. If the arguments match or some valid conversion exists (float64 to int for example) it will call your function with the received arguments. If your function returns no error the resulting value of your function will be JSON encoded and sent as response to the request. If some error occurs the text of the error will be send with the status code ``http.StatusBadRequest``.\n\n#### Javascript\n\nThe Javascript part of nra does nothing more than sending a ``POST`` request to ``/rpc/YOUR_FUNCTION_NAME`` with JSON encoded arguments to your backend.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigjk%2Fnra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigjk%2Fnra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigjk%2Fnra/lists"}