Class: JSONRPC2::Interface

Inherits:
Object
  • Object
show all
Extended by:
TextileEmitter
Defined in:
lib/jsonrpc2/interface.rb

Overview

Base class for JSONRPC2 interface

Class Attribute Summary collapse

Authentication collapse

Rack-related collapse

DSL collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TextileEmitter

about_method, method_to_textile, to_textile, to_textile_group

Constructor Details

#initialize(env) ⇒ Interface

Create new interface object

Parameters:

  • env (Hash)

    Rack environment



74
75
76
77
# File 'lib/jsonrpc2/interface.rb', line 74

def initialize(env)
  @_jsonrpc_env = env
  @_jsonrpc_request = Rack::Request.new(env)
end

Class Attribute Details

.aboutObject (readonly)

Returns the value of attribute about.



309
310
311
# File 'lib/jsonrpc2/interface.rb', line 309

def about
  @about
end

.typesObject (readonly)

Returns the value of attribute types.



309
310
311
# File 'lib/jsonrpc2/interface.rb', line 309

def types
  @types
end

Class Method Details

.___append_param(name, type, options) ⇒ Object

Store parameter in internal hash when building API



184
185
186
187
188
189
190
# File 'lib/jsonrpc2/interface.rb', line 184

def ___append_param name, type, options
  @params ||= []
  unless options.has_key?(:required)
    options[:required] = true
  end
  @params << options.merge({ :name => name, :type => type })
end

.auth_with(*args) ⇒ #check?

Get/set authenticator object for API interface - see Auth and BasicAuth

Parameters:

  • args (#check)

    An object that responds to check(environment, json_call_data)

Returns:

  • (#check, nil)

    Currently set object or nil



28
29
30
31
32
33
34
# File 'lib/jsonrpc2/interface.rb', line 28

def auth_with *args
  if args.empty?
    return @auth_with
  else
    @auth_with = args[0]
  end
end

.call(environment) ⇒ Array<Fixnum, Hash<String,String>, Array<String>>

Rack compatible call handler

Parameters:

  • environment (Hash)

    Rack environment hash

Returns:

  • (Array<Fixnum, Hash<String,String>, Array<String>>)

    Rack-compatible response



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/jsonrpc2/interface.rb', line 44

def call(environment)
  request = Rack::Request.new(environment)
  catch :rack_response do
    best = JSONRPC2::HTTPUtils.which(environment['HTTP_ACCEPT'], %w[text/html application/json-rpc application/json])

    if request.path_info =~ %r'/_assets'
      best = 'text/html' # hack for assets
    end

    case best
    when 'text/html', 'text/css', 'image/png' # Assume browser
      JSONRPC2::HTML.call(self, request)
    when 'application/json-rpc', 'application/json', nil # Assume correct by default
      environment['rack.input'].rewind
      data = JSON.parse(environment['rack.input'].read)
      self.new(environment).rack_dispatch(data)
    else
      [406, {'Content-Type' => 'text/html'}, 
        ["<!DOCTYPE html><html><head><title>Media type mismatch</title></head><body>I am unable to acquiesce to your request</body></html>"]]
    end
  end
end

.desc(str) ⇒ Object

Set description for next method



226
227
228
# File 'lib/jsonrpc2/interface.rb', line 226

def desc str
  @desc = str
end

.example(desc, code) ⇒ Object

Add an example for next method



231
232
233
234
# File 'lib/jsonrpc2/interface.rb', line 231

def example desc, code
  @examples ||= []
  @examples << { :desc => desc, :code => code }
end

.introduction(str = nil) ⇒ Object

Sets introduction for interface



271
272
273
# File 'lib/jsonrpc2/interface.rb', line 271

def introduction str = nil
  @introduction = str if str
end

.method_added(name) ⇒ Object

Catch methods added to class & store documentation



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/jsonrpc2/interface.rb', line 278

def method_added(name)
  return if self == JSONRPC2::Interface
  @about ||= {}
  method = {}
  method[:params] = @params if @params
  method[:returns] = @result if @result
  method[:desc] = @desc if @desc
  method[:examples] = @examples if @examples
  
  if method.empty?
    if public_methods(false).include?(name)
      unless @nodoc
        #logger.info("#{name} has no API documentation... :(")
      end
    else
      #logger.debug("#{name} isn't public - so no API")
    end
  else
    method[:name] = name
    method[:section] = @current_section
    method[:index] = @about.size
    @about[name.to_s] = method
  end

  @result = nil
  @params = nil
  @desc = nil
  @examples = nil
  @nodoc = false
end

.nodocObject

Exclude next method from documentation



261
262
263
# File 'lib/jsonrpc2/interface.rb', line 261

def nodoc
  @nodoc = true
end

.optional(name, type, desc = nil, options = nil) ⇒ Object

Define an optional parameter for next method



210
211
212
213
214
215
216
217
218
# File 'lib/jsonrpc2/interface.rb', line 210

def optional name, type, desc = nil, options = nil
  if options.nil? && desc.is_a?(Hash)
    options, desc = desc, nil
  end
  options ||= {}
  options[:desc] = desc if desc.is_a?(String)

  ___append_param(name, type, options.merge(:required => false))
end

.param(name, type, desc = nil, options = nil) ⇒ Object

Define a named parameter of type #type for next method

Parameters:

  • name (String)

    parameter name

  • type (String)

    description of type see Types



199
200
201
202
203
204
205
206
207
# File 'lib/jsonrpc2/interface.rb', line 199

def param name, type, desc = nil, options = nil
  if options.nil? && desc.is_a?(Hash)
    options, desc = desc, nil
  end
  options ||= {}
  options[:desc] = desc if desc.is_a?(String)
  
  ___append_param name, type, options
end

.result(type, desc = nil) ⇒ Object

Define type of return value for next method



221
222
223
# File 'lib/jsonrpc2/interface.rb', line 221

def result type, desc = nil
  @result = { :type => type, :desc => desc }
end

.section(name, summary = nil) ⇒ Object

Group methods



249
250
251
252
253
254
255
256
257
258
# File 'lib/jsonrpc2/interface.rb', line 249

def section name, summary=nil
  @sections ||= []
  @sections << {:name => name, :summary => summary}

  @current_section = name
  if block_given?
    yield
    @current_section = nil
  end
end

.title(str = nil) ⇒ Object

Set interface title



266
267
268
# File 'lib/jsonrpc2/interface.rb', line 266

def title str = nil
  @title = str if str
end

.type(name, *fields) ⇒ Object

Define a custom type



237
238
239
240
241
242
243
244
245
246
# File 'lib/jsonrpc2/interface.rb', line 237

def type name, *fields
  @types ||= {}
  type = JsonObjectType.new(name, fields)

  if block_given?
    yield(type)
  end

  @types[name] = type
end

Instance Method Details

#dispatch(rpc_data) ⇒ Hash, Array

Dispatch call to api method(s)

Parameters:

  • rpc_data (Hash, Array)

    Array of calls or Hash containing one call

Returns:

  • (Hash, Array)

    Depends on input, but either a hash result or an array of results corresponding to calls.



90
91
92
93
94
95
96
97
# File 'lib/jsonrpc2/interface.rb', line 90

def dispatch(rpc_data)
  case rpc_data
  when Array
    rpc_data.map { |rpc| dispatch_single(rpc) }.to_json
  else
    dispatch_single(rpc_data).to_json
  end
end

#rack_dispatch(rpcData) ⇒ Object

Internal



79
80
81
82
83
84
# File 'lib/jsonrpc2/interface.rb', line 79

def rack_dispatch(rpcData)
  catch(:rack_response) do
    json = dispatch(rpcData)
    [200, {'Content-Type' => 'application/json-rpc'}, [json]]
  end
end