Skip to content

BigJk/nra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nra

Documentation Go Report Card

nra (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.

Javascript Code

This code is all you need to call a function that is defined in your Go code. Just copy and paste it into your Javascript.

function call(func, ...args) {
  return new Promise(function(resolve, reject) {
    var request = new XMLHttpRequest();
    request.open('POST', '/rpc/' + func, true);

    request.onload = function() {
      if (request.status === 200) {
        resolve(JSON.parse(request.responseText));
      } else {
        reject(request.responseText);
      }
    };

    request.onerror = function() {
      reject(request.responseText);
    };

    request.send(JSON.stringify(args));
  });
}

Minified

function 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))})}

Example

Imagine 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.

package main

import (
	"net/http"
	"strings"
	"fmt"

	"github.com/BigJk/nra"
)

func main() {
  // RPC functions should be prefixed
  // with the '/rpc/' path when registering.
  http.HandleFunc("/rpc/get_logs", nra.MustBind(func(search string, limit int) ([]string, error) {
    // lets generate some fake data here.
    // normally some cool database access
    // would happen here.
    fakeLogs := make([]string, limit)
    for i := 0; i < limit; i++ {
      fakeLogs[i] = fmt.Sprintf("%d. some data %s", i, search)
    }
    return fakeLogs, nil
  }))

  // host your html, javascript etc.
  http.Handle("/", http.FileServer(http.Dir("static")))

  // start the server
  http.ListenAndServe(":8765", nil)
}

Somewhere in your Javascript

call('get_logs', 'error', 100).then(function(logs) {
  console.log(logs);
}, function(err) {
  console.log(err);
})

Thats 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.

Structs

Passing structs from Javascript to Go and back is also supported.

type Search struct {
  Text   string `json:"text"`
  Limit  int    `json:"limit"`
}

type DataEntry struct {
  Text   string    `json:"text"`
  Time   time.Time `json:"time"`
}

http.HandleFunc("/rpc/get_structs", nra.MustBind(func(search Search) ([]DataEntry, error) {
  // search and return your DataEntries
}))
call('get_logs', { text: "my search", limit: 250 }).then(function(data_entries) {
  console.log(data_entries);
}, function(err) {
  console.log(err);
})

How does it work?

Go

Feel 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.

Javascript

The Javascript part of nra does nothing more than sending a POST request to /rpc/YOUR_FUNCTION_NAME with JSON encoded arguments to your backend.

About

Minimal RPC library to call Go from Javascript

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages