Module: ActionWebService::Scaffolding::ClassMethods
- Defined in:
- lib/action_web_service/scaffolding.rb
Overview
Web service invocation scaffolding provides a way to quickly invoke web service methods in a controller. The generated scaffold actions have default views to let you enter the method parameters and view the results.
Example:
class ApiController < ActionController
web_service_scaffold :invoke
end
This example generates an invoke
action in the ApiController
that you can navigate to from your browser, select the API method, enter its parameters, and perform the invocation.
If you want to customize the default views, create the following views in “app/views”:
-
action_name/methods.html.erb
-
action_name/parameters.html.erb
-
action_name/result.html.erb
-
action_name/layout.html.erb
Where action_name
is the name of the action you gave to ClassMethods#web_service_scaffold.
You can use the default views in RAILS_DIR/lib/action_web_service/templates/scaffolds
as a guide.
Instance Method Summary collapse
-
#web_service_scaffold(action_name) ⇒ Object
Generates web service invocation scaffolding for the current controller.
Instance Method Details
#web_service_scaffold(action_name) ⇒ Object
Generates web service invocation scaffolding for the current controller. The given action name can then be used as the entry point for invoking API methods from a web browser.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/action_web_service/scaffolding.rb', line 41 def web_service_scaffold(action_name) add_template_helper(Helpers) module_eval <<-"end_eval", __FILE__, __LINE__ + 1 def #{action_name} if request.get? setup_invocation_assigns render_invocation_scaffold 'methods' end end def #{action_name}_method_params if request.get? setup_invocation_assigns render_invocation_scaffold 'parameters' end end def #{action_name}_submit if request.post? setup_invocation_assigns protocol_name = params['protocol'] ? params['protocol'].to_sym : :soap case protocol_name when :soap @protocol = Protocol::Soap::SoapProtocol.create(self) when :xmlrpc @protocol = Protocol::XmlRpc::XmlRpcProtocol.create(self) end bm = Benchmark.measure do @protocol.register_api(@scaffold_service.api) post_params = params['method_params'] ? params['method_params'].dup : nil params = [] @scaffold_method.expects.each_with_index do |spec, i| params << post_params[i.to_s] end if @scaffold_method.expects params = @scaffold_method.cast_expects(params) method_name = public_method_name(@scaffold_service.name, @scaffold_method.public_name) @method_request_xml = @protocol.encode_request(method_name, params, @scaffold_method.expects) new_request = @protocol.encode_action_pack_request(@scaffold_service.name, @scaffold_method.public_name, @method_request_xml) prepare_request(new_request, @scaffold_service.name, @scaffold_method.public_name) self.request = new_request if @scaffold_container.dispatching_mode != :direct request.parameters['action'] = @scaffold_service.name end dispatch_web_service_request @method_response_xml = response.body method_name, obj = @protocol.decode_response(@method_response_xml) return if handle_invocation_exception(obj) @method_return_value = @scaffold_method.cast_returns(obj) end @method_elapsed = bm.real reset_invocation_response render_invocation_scaffold 'result' end end private def setup_invocation_assigns @scaffold_class = self.class @scaffold_action_name = "#{action_name}" @scaffold_container = WebServiceModel::Container.new(self) if params['service'] && params['method'] @scaffold_service = @scaffold_container.services.find{ |x| x.name == params['service'] } @scaffold_method = @scaffold_service.api_methods[params['method']] end end def render_invocation_scaffold(action) customized_template = "\#{self.class.controller_path}/#{action_name}/\#{action}" default_template = scaffold_path(action) begin content = view_context.render(:file => customized_template) rescue ActionView::MissingTemplate content = view_context.render(:file => default_template) end @content_for_layout = content #if self.action_has_layout? # render :file => self.send(:_layout), :use_full_path => true #else render :file => scaffold_path("layout") #end end def scaffold_path(template_name) File.dirname(__FILE__) + "/templates/scaffolds/" + template_name + ".html.erb" end def reset_invocation_response self.instance_variable_set(:@_response_body, nil) response.instance_variable_set :@header, Rack::Utils::HeaderHash.new("cookie" => [], 'Content-Type' => 'text/html') end def public_method_name(service_name, method_name) if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::XmlRpc::XmlRpcProtocol) service_name + '.' + method_name else method_name end end def prepare_request(new_request, service_name, method_name) new_request.parameters.update(request.parameters) request.env.each{ |k, v| new_request.env[k] = v unless new_request.env.has_key?(k) } if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::Soap::SoapProtocol) new_request.env['HTTP_SOAPACTION'] = "/\#{controller_name()}/\#{service_name}/\#{method_name}" end end def handle_invocation_exception(obj) exception = nil if obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && obj.detail.cause.is_a?(Exception) exception = obj.detail.cause elsif obj.is_a?(XMLRPC::FaultException) exception = obj end return unless exception reset_invocation_response rescue_action(exception) true end end_eval end |