Coder Social home page Coder Social logo

jsonrpc's Introduction

jsonrpc

my own JSONRPCv2 implementation

Usage

Creating a server API is easy! Simply subclass JSONRPC and create properties and methods per your own requirements. After that, build_routes() needs to be called with an instance of your subclass as the first argument (optionally, a second argument of a lambda can be used to provide a session to api calls).

Any subclass of JSONRPC, once instantiated either by the server or indirectly by a client, will be a remote object clients can interact with. In other words, suppose you wished to return an interface that represented an object in a database and that you wished to have callable functions, all you would need to do is create a class as previously described and return an instance of it from a function in a previously declared class.

Example Server:

class Car(JSONRPC):
  def __init__(self, id):
    super(Car, self).__init__(self)
    self.id = id
  def move(self, new_x, new_y):
    db.update(self.id, ('x', 'y'), [new_x, new_y]
  def cur_x(self):
    return db.select(Car.id==self.id).x
  def cur_y(self):
    return db.select(Car.id==self.id).y
  
class Road(JSONRPC):
  def first_car(self):
    return Car(0)
  def remove_car(self, c):  # the serialization layer translates JSONRPC clients to a form suitable for clients, who can then pass them back to the server
    db.delete(Car.id==c.id)
  def echo(self, val):
    return val
  
build_routes(Road())

Example Client:

client = APIClient('http://localhost:9055/api')
c = client.first_car()
c.move(100, 100)
client.remove_car(c)

One can also use the batch functionality of JSONRPCv2 as each APIClient is also a context manager!

with client.first_car() as car:
  car.move(100, 100)
  car.move(car.val(car.cur_x())+50, 200)  # calling .val(obj) causes the passed object to be evaluated before the batch is executed
car.__results__ == [0, None, None] # note how the usual semantics break; the first element is expected to be 100 but .val forces evaluation before the first call to .move
# results are .val calls, in order, followed by the regular calls

Java

You can either use the ApiClient as is and use casting or you can specify an interface and a proxy will be returned.

Example for the former:

ApiClient c = new ApiClient("http://localhost:9055/api");
ApiClient car = (ApiClient)c.call("first_car");
int x = (Integer)car.call("cur_x");  // cur_x is a function on the remote object
int id = (Integer)car.get("id");  // id is a property though

Example for the latter:

interface Car extends PythonMagic { // must extend PythonMagic
  public int id();
  public int cur_x();
  public int cur_y();
  public void move(int x, int y);
}
Car car = c.call("first_car").<Car>proxy(Car.class);
car.move(1, 1);
car.move(10, 1);

And we can do batch calls in java too!

List<Object> results = c.batch(new BatchCallRunnable() {
  @Override
  public void run(BatchClient r) {
    r.val(r.call("first_car")).move(1, 100);  // have to get the value from the .call before  using it
    r.call("echo", "hello world");
  }
}
// results now contains [ApiClient instance, null, "hello world"] for the calls to first_car and echo
// results are .val calls, in order, followed by regular function calls

I have yet to test proxy support for batch calls, it should work though as it ultimately ends up using the "call" function that batch calls use

JavaScript

Similar to python, except the batch support is implemented slightly differently due to the lack of context managers in javascript.

var client = jsonrpc("/api");
client.echo("hello world");
var results = client.batch(function(r) {
  r.echo("hello world");
  r.val(r.first_car()).move(100, 100); // same as in Java, gotta get the value first
  r.echo("hello " + r.val(r.echo("world")));
}
results == [JSONRPCCLIENT instance, "world", "hello world", null, "hello world"]
// results are .val calls, in order, followed by regular function calls

We can also make async calls with a callback

client.echo.async("hello world", function(result){
  console.log(result);  // result is simply the return value from the function call
}

We can't however do async batch calls as I have yet to figure out how to pass the correct "this" around

jsonrpc's People

Contributors

r0ssar00 avatar kevinross avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.