Class: Barrister::Client

Inherits:
Object
  • Object
show all
Includes:
Barrister
Defined in:
lib/barrister.rb

Overview

This is the main class used when writing a client for a Barrister service.

Clients accept a transport class on the constructor which encapsulates serialization and network communciation. Currently this module only provides a basic HTTP transport, but other transports can be easily written.

Direct Known Subclasses

BatchClient

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Barrister

contract_from_file, #err_resp, #ok_resp, parse_method, rand_str

Constructor Details

#initialize(trans, validate_req = true, validate_result = true) ⇒ Client

Create a new Client. This immediately makes a ‘barrister-idl` request to fetch the IDL from the Server. A Barrister::Contract is created from this IDL and used to expose proxy objects for each interface on the IDL.

  • ‘trans` - Transport instance to use. Must have a `request(req)` method

  • ‘validate_req` - If true, request parameters will be validated against the IDL

    before sending the request to the transport.
    
  • ‘validate_result` - If true, the result from the server will be validated against the IDL



285
286
287
288
289
290
291
292
# File 'lib/barrister.rb', line 285

def initialize(trans, validate_req=true, validate_result=true)
  @trans           = trans
  @validate_req    = validate_req
  @validate_result = validate_result

  load_contract
  init_proxies
end

Instance Attribute Details

#transObject

Returns the value of attribute trans.



274
275
276
# File 'lib/barrister.rb', line 274

def trans
  @trans
end

Instance Method Details

#get_metaObject

Returns the hash of metadata from the Contract, which includes the date the IDL was translated to JSON, the Barrister version used to translate the IDL, and a checksum of the IDL which can be used to detect version changes.



297
298
299
# File 'lib/barrister.rb', line 297

def get_meta
  return @contract.meta
end

#init_proxiesObject

Internal method invoked by ‘initialize`. Iterates through the Contract and creates proxy classes for each interface.



322
323
324
325
326
327
328
329
330
# File 'lib/barrister.rb', line 322

def init_proxies
  singleton = class << self; self end
  @contract.interfaces.each do |iface|
    proxy = InterfaceProxy.new(self, iface)
    singleton.send :define_method, iface.name do
      return proxy
    end
  end
end

#load_contractObject

Internal method invoked by ‘initialize`. Sends a `barrister-idl` request to the server and creates a Barrister::Contract with the result.



310
311
312
313
314
315
316
317
318
# File 'lib/barrister.rb', line 310

def load_contract
  req = { "jsonrpc" => "2.0", "id" => "1", "method" => "barrister-idl" }
  resp = @trans.request(req)
  if resp.key?("result")
    @contract = Contract.new(resp["result"])
  else
    raise RpcException.new(-32000, "Invalid contract response: #{resp}")
  end
end

#request(method, params) ⇒ Object

Sends a JSON-RPC request. This method is automatically called by the proxy classes, so in practice you don’t usually call it directly. However, it is available if you wish to avoid the use of proxy classes.

  • ‘method` - string of the method to invoke. Format: “interface.function”.

    For example: "ContactService.saveContact"
    
  • ‘params` - parameters to pass to the function. Must be an Array



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/barrister.rb', line 339

def request(method, params)
  req = { "jsonrpc" => "2.0", "id" => Barrister::rand_str(22), "method" => method }
  if params
    req["params"] = params
  end
  
  # We always validate that the method is valid
  err_resp, iface, func = @contract.resolve_method(req)
  if err_resp != nil
    return err_resp
  end
    
  if @validate_req
    err_resp = @contract.validate_params(req, func)
    if err_resp != nil
      return err_resp
    end
  end
  
  # This makes the request to the server
  resp = @trans.request(req)
  
  if @validate_result && resp != nil && resp.key?("result")
    err_resp = @contract.validate_result(req, resp["result"], func)
    if err_resp != nil
      resp = err_resp
    end
  end
  
  return resp
end

#start_batchObject

Returns a Barrister::BatchClient instance that is associated with this Client instance

Batches let you send multiple requests in a single round trip



304
305
306
# File 'lib/barrister.rb', line 304

def start_batch
  return BatchClient.new(self, @contract)
end