apipie-rails 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +3 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +5 -0
- data/APACHE-LICENSE-2.0 +202 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +115 -0
- data/MIT-LICENSE +20 -0
- data/NOTICE +4 -0
- data/README.rdoc +365 -0
- data/Rakefile +13 -0
- data/apipie-rails.gemspec +27 -0
- data/app/controllers/apipie/apipies_controller.rb +60 -0
- data/app/public/apipie/javascripts/apipie.js +6 -0
- data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +138 -0
- data/app/public/apipie/javascripts/bundled/bootstrap.js +1726 -0
- data/app/public/apipie/javascripts/bundled/jquery-1.7.2.js +9404 -0
- data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
- data/app/public/apipie/stylesheets/application.css +7 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +12 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +689 -0
- data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
- data/app/views/apipie/apipies/_params.html.erb +22 -0
- data/app/views/apipie/apipies/_params_plain.html.erb +16 -0
- data/app/views/apipie/apipies/index.html.erb +36 -0
- data/app/views/apipie/apipies/method.html.erb +63 -0
- data/app/views/apipie/apipies/plain.html.erb +70 -0
- data/app/views/apipie/apipies/resource.html.erb +82 -0
- data/app/views/apipie/apipies/static.html.erb +101 -0
- data/app/views/layouts/apipie/apipie.html.erb +37 -0
- data/lib/apipie-rails.rb +12 -0
- data/lib/apipie/apipie_module.rb +105 -0
- data/lib/apipie/application.rb +225 -0
- data/lib/apipie/client/generator.rb +105 -0
- data/lib/apipie/client/template/Gemfile.tt +5 -0
- data/lib/apipie/client/template/README.tt +3 -0
- data/lib/apipie/client/template/base.rb.tt +33 -0
- data/lib/apipie/client/template/bin.rb.tt +110 -0
- data/lib/apipie/client/template/cli.rb.tt +25 -0
- data/lib/apipie/client/template/cli_command.rb.tt +129 -0
- data/lib/apipie/client/template/client.rb.tt +10 -0
- data/lib/apipie/client/template/resource.rb.tt +17 -0
- data/lib/apipie/dsl_definition.rb +139 -0
- data/lib/apipie/error_description.rb +21 -0
- data/lib/apipie/extractor.rb +143 -0
- data/lib/apipie/extractor/collector.rb +113 -0
- data/lib/apipie/extractor/recorder.rb +122 -0
- data/lib/apipie/extractor/writer.rb +356 -0
- data/lib/apipie/helpers.rb +24 -0
- data/lib/apipie/markup.rb +45 -0
- data/lib/apipie/method_description.rb +150 -0
- data/lib/apipie/param_description.rb +87 -0
- data/lib/apipie/railtie.rb +9 -0
- data/lib/apipie/resource_description.rb +83 -0
- data/lib/apipie/routing.rb +13 -0
- data/lib/apipie/static_dispatcher.rb +60 -0
- data/lib/apipie/validator.rb +292 -0
- data/lib/apipie/version.rb +3 -0
- data/lib/tasks/apipie.rake +156 -0
- data/rel-eng/packages/.readme +3 -0
- data/rel-eng/tito.props +5 -0
- data/rubygem-apipie-rails.spec +72 -0
- data/spec/controllers/apipies_controller_spec.rb +132 -0
- data/spec/controllers/users_controller_spec.rb +390 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +6 -0
- data/spec/dummy/app/controllers/twitter_example_controller.rb +302 -0
- data/spec/dummy/app/controllers/users_controller.rb +223 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +21 -0
- data/spec/dummy/config/environment.rb +8 -0
- data/spec/dummy/config/environments/development.rb +25 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/apipie.rb +64 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +21 -0
- data/spec/dummy/doc/apipie_examples.yml +28 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +202 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +32 -0
- metadata +312 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module <%= class_base %>Client
|
5
|
+
class Base
|
6
|
+
attr_reader :client
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@client = RestClient::Resource.new(config[:base_url], :user => config[:username], :password => config[:password])
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(method, path, params = {})
|
13
|
+
ret = client[path].send(method, params)
|
14
|
+
data = JSON.parse(ret.body) rescue ret.body
|
15
|
+
return data, ret
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_params!(options, valid_keys)
|
19
|
+
return unless options.is_a?(Hash)
|
20
|
+
invalid_keys = options.keys - (valid_keys.is_a?(Hash) ? valid_keys.keys : valid_keys)
|
21
|
+
raise ArgumentError, "Invalid keys: #{invalid_keys.join(", ")}" unless invalid_keys.empty?
|
22
|
+
|
23
|
+
if valid_keys.is_a? Hash
|
24
|
+
valid_keys.each do |key, keys|
|
25
|
+
if options[key]
|
26
|
+
validate_params!(options[key], keys)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems" # ruby1.9 doesn't "require" it though
|
3
|
+
require "pathname"
|
4
|
+
require "thor"
|
5
|
+
require 'thor/core_ext/file_binary_read'
|
6
|
+
|
7
|
+
$: << File.expand_path("../../lib", __FILE__)
|
8
|
+
require "<%= name %>_client"
|
9
|
+
require "<%= name %>_client/cli_command"
|
10
|
+
|
11
|
+
module <%= class_base %>Cli
|
12
|
+
class Main < Thor
|
13
|
+
|
14
|
+
def help(meth = nil)
|
15
|
+
if meth && !self.respond_to?(meth)
|
16
|
+
initialize_thorfiles(meth)
|
17
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
18
|
+
self.class.handle_no_task_error(task, false) if klass.nil?
|
19
|
+
klass.start(["-h", task].compact, :shell => self.shell)
|
20
|
+
else
|
21
|
+
say "<%= name.capitalize %> CLI"
|
22
|
+
say
|
23
|
+
invoke :commands
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "commands [SEARCH]", "List the available commands"
|
28
|
+
def commands(search="")
|
29
|
+
initialize_thorfiles
|
30
|
+
klasses = Thor::Base.subclasses
|
31
|
+
display_klasses(false, false, klasses)
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
private
|
36
|
+
def dispatch(task, given_args, given_options, config)
|
37
|
+
parser = Thor::Options.new({:username => Thor::Option.parse(%w[username -u], :string),
|
38
|
+
:password => Thor::Option.parse(%w[password -p], :string)})
|
39
|
+
opts = parser.parse(given_args)
|
40
|
+
<%= class_base %>Client.client_config[:username] = opts["username"]
|
41
|
+
<%= class_base %>Client.client_config[:password] = opts["password"]
|
42
|
+
#remaining = parser.instance_variable_get("@unknown") # TODO: this is an ugly hack :(
|
43
|
+
remaining = parser.remaining
|
44
|
+
super(task, remaining, given_options, config)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def method_missing(meth, *args)
|
51
|
+
meth = meth.to_s
|
52
|
+
initialize_thorfiles(meth)
|
53
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
54
|
+
args.unshift(task) if task
|
55
|
+
klass.start(args, :shell => self.shell)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Load the thorfiles. If relevant_to is supplied, looks for specific files
|
59
|
+
# in the thor_root instead of loading them all.
|
60
|
+
#
|
61
|
+
# By default, it also traverses the current path until find Thor files, as
|
62
|
+
# described in thorfiles. This look up can be skipped by suppliying
|
63
|
+
# skip_lookup true.
|
64
|
+
#
|
65
|
+
def initialize_thorfiles(relevant_to=nil, skip_lookup=false)
|
66
|
+
thorfiles.each do |f|
|
67
|
+
Thor::Util.load_thorfile(f, nil, options[:debug])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def thorfiles
|
72
|
+
Dir[File.expand_path("../../lib/<%= name %>_client/commands/*.thor", __FILE__)]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Display information about the given klasses. If with_module is given,
|
76
|
+
# it shows a table with information extracted from the yaml file.
|
77
|
+
#
|
78
|
+
def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
|
79
|
+
klasses -= [Thor, Main, ::<%= class_base %>Client::CliCommand] unless show_internal
|
80
|
+
|
81
|
+
show_modules if with_modules && !thor_yaml.empty?
|
82
|
+
|
83
|
+
list = Hash.new { |h,k| h[k] = [] }
|
84
|
+
groups = []
|
85
|
+
|
86
|
+
# Get classes which inherit from Thor
|
87
|
+
(klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_tasks(false) }
|
88
|
+
|
89
|
+
# Get classes which inherit from Thor::Base
|
90
|
+
groups.map! { |k| k.printable_tasks(false).first }
|
91
|
+
list["root"] = groups
|
92
|
+
|
93
|
+
# Order namespaces with default coming first
|
94
|
+
list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
|
95
|
+
list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
|
96
|
+
end
|
97
|
+
|
98
|
+
def display_tasks(namespace, list) #:nodoc:
|
99
|
+
say namespace
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
<%= class_base %>Cli::Main.start
|
107
|
+
rescue RestClient::Exception => e
|
108
|
+
$stderr.puts e.message
|
109
|
+
exit 1
|
110
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class <%= resource_name.camelize %> < <%= class_base %>Client::CliCommand
|
2
|
+
|
3
|
+
<% resource[:methods].each do |method| -%>
|
4
|
+
desc '<%= method[:name] %>', '<%= api(method)[:short_description] %>'
|
5
|
+
<% params_in_path(method).each do |param| -%>
|
6
|
+
method_option :<%= param %>, :required => 'true'
|
7
|
+
<% end
|
8
|
+
method[:params].map {|p| p[:expected_type] == "hash" ? (p[:params] || p) : p}.flatten.each do |param| -%>
|
9
|
+
method_option :<%= param[:name] %>, :required => <%= param[:required] ? 'true' : 'false' %>, :desc => '<%= plaintext(param[:description]) %>', :type => :<%= param[:expected_type] %>
|
10
|
+
<% end -%>
|
11
|
+
def <%= method[:name] %>
|
12
|
+
<% if params_in_path(method).any? || transformation_hash(method).any?
|
13
|
+
transform_options_params = [params_in_path(method).inspect]
|
14
|
+
transform_options_params << transformation_hash(method).inspect if transformation_hash(method).any? -%>
|
15
|
+
<%= (params_in_path(method) + ["options"]).join(", ") %>, *_ = transform_options(<%= transform_options_params.join(", ").html_safe %>)
|
16
|
+
<% end
|
17
|
+
|
18
|
+
client_args = params_in_path(method).dup
|
19
|
+
client_args << "options" if method[:params].any? -%>
|
20
|
+
data, resp = client.<%= method[:name] %><%= "(#{client_args.join(", ")})" if client_args.any? %>
|
21
|
+
print_data(data)
|
22
|
+
end
|
23
|
+
|
24
|
+
<% end -%>
|
25
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module <%= class_base %>Client
|
2
|
+
class CliCommand < Thor
|
3
|
+
no_tasks do
|
4
|
+
def client
|
5
|
+
resource_class = <%= class_base %>Client::Resources.const_get(self.class.name[/[^:]*$/])
|
6
|
+
@client ||= resource_class.new(<%= class_base %>Client.client_config)
|
7
|
+
end
|
8
|
+
|
9
|
+
def transform_options(inline_params, transform_hash = {})
|
10
|
+
ret = inline_params.map { |p| options[p] }
|
11
|
+
|
12
|
+
# we use not mentioned params without change
|
13
|
+
transformed_options = (options.keys - transform_hash.values.flatten - inline_params).reduce({}) { |h, k| h.update(k => options[k]) }
|
14
|
+
|
15
|
+
transform_hash.each do |sub_key, params|
|
16
|
+
transformed_options[sub_key] = {}
|
17
|
+
params.each { |p| transformed_options[sub_key][p] = options[p] if options.has_key?(p) }
|
18
|
+
end
|
19
|
+
|
20
|
+
ret << transformed_options
|
21
|
+
return *ret
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_data(data)
|
25
|
+
case data
|
26
|
+
when Array
|
27
|
+
print_big_table(table_from_array(data))
|
28
|
+
when Hash
|
29
|
+
print_table(table_from_hash(data))
|
30
|
+
else
|
31
|
+
print_unknown(data)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# unifies the data for further processing. e.g.
|
36
|
+
#
|
37
|
+
# { "user" => {"username" => "test", "password" => "changeme" }
|
38
|
+
#
|
39
|
+
# becomes:
|
40
|
+
#
|
41
|
+
# { "username" => "test", "password" => "changeme" }
|
42
|
+
def normalize_item_data(item)
|
43
|
+
if item.size == 1 && item.values.first.is_a?(Hash)
|
44
|
+
item.values.first
|
45
|
+
else
|
46
|
+
item
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def table_from_array(data)
|
51
|
+
return [] if data.empty?
|
52
|
+
table = []
|
53
|
+
items = data.map { |item| normalize_item_data(item) }
|
54
|
+
columns = items.first.keys
|
55
|
+
table << columns
|
56
|
+
items.each do |item|
|
57
|
+
row = columns.map { |c| item[c] }
|
58
|
+
table << row.map(&:to_s)
|
59
|
+
end
|
60
|
+
return table
|
61
|
+
end
|
62
|
+
|
63
|
+
def table_from_hash(data)
|
64
|
+
return [] if data.empty?
|
65
|
+
table = []
|
66
|
+
normalize_item_data(data).each do |k, v|
|
67
|
+
table << ["#{k}:",v].map(&:to_s)
|
68
|
+
end
|
69
|
+
table
|
70
|
+
end
|
71
|
+
|
72
|
+
def print_unknown(data)
|
73
|
+
say data
|
74
|
+
end
|
75
|
+
|
76
|
+
def print_big_table(table, options={})
|
77
|
+
return if table.empty?
|
78
|
+
|
79
|
+
formats, ident, colwidth = [], options[:ident].to_i, options[:colwidth]
|
80
|
+
options[:truncate] = terminal_width if options[:truncate] == true
|
81
|
+
|
82
|
+
formats << "%-#{colwidth + 2}s" if colwidth
|
83
|
+
start = colwidth ? 1 : 0
|
84
|
+
|
85
|
+
start.upto(table.first.length - 2) do |i|
|
86
|
+
maxima ||= table.max{|a,b| a[i].size <=> b[i].size }[i].size
|
87
|
+
formats << "%-#{maxima + 2}s"
|
88
|
+
end
|
89
|
+
|
90
|
+
formats << "%s"
|
91
|
+
formats[0] = formats[0].insert(0, " " * ident)
|
92
|
+
|
93
|
+
header_printed = false
|
94
|
+
table.each do |row|
|
95
|
+
sentence = ""
|
96
|
+
|
97
|
+
row.each_with_index do |column, i|
|
98
|
+
sentence << formats[i] % column.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
sentence = truncate(sentence, options[:truncate]) if options[:truncate]
|
102
|
+
$stdout.puts sentence
|
103
|
+
say(set_color("-" * sentence.size, :green)) unless header_printed
|
104
|
+
header_printed = true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
class << self
|
111
|
+
def help(shell, subcommand = true)
|
112
|
+
list = self.printable_tasks(true, subcommand)
|
113
|
+
Thor::Util.thor_classes_in(self).each do |klass|
|
114
|
+
list += printable_tasks(false)
|
115
|
+
end
|
116
|
+
list.sort!{ |a,b| a[0] <=> b[0] }
|
117
|
+
|
118
|
+
shell.say
|
119
|
+
shell.print_table(list, :indent => 2, :truncate => true)
|
120
|
+
shell.say
|
121
|
+
Thor.send(:class_options_help, shell)
|
122
|
+
end
|
123
|
+
|
124
|
+
def banner(task, namespace = nil, subcommand = false)
|
125
|
+
task.name
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require '<%= name %>_client/base'
|
2
|
+
|
3
|
+
resource_files = Dir[File.expand_path('../<%= name %>_client/resources/*.rb', __FILE__)]
|
4
|
+
resource_files.each { |f| require f }
|
5
|
+
|
6
|
+
module <%= class_base %>Client
|
7
|
+
def self.client_config
|
8
|
+
@client_config ||= {:base_url => "http://localhost:3000"}
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module <%= class_base %>Client
|
2
|
+
module Resources
|
3
|
+
class <%= resource_name.camelize %> < <%= class_base %>Client::Base
|
4
|
+
<% resource[:methods].each do |method| -%>
|
5
|
+
|
6
|
+
def <%= method[:name] %><%= "(#{ client_args(method).join(", ") })" if client_args(method).any? %>
|
7
|
+
<% if method[:params].any? -%>
|
8
|
+
validate_params!(params, <%= validation_hash(method).inspect.html_safe %>)
|
9
|
+
<% end -%>
|
10
|
+
call(:<%= api(method)[:http_method].downcase %>, "<%= substituted_url(method) %>"<%=
|
11
|
+
(api(method)[:http_method].downcase == 'get' ? ", :params => params" : ", params") if method[:params].any? %>)
|
12
|
+
end
|
13
|
+
<% end -%>
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# Apipie DSL functions.
|
2
|
+
|
3
|
+
module Apipie
|
4
|
+
|
5
|
+
# DSL is a module that provides #api, #error, #param, #error.
|
6
|
+
module DSL
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Describe whole resource
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# api :desc => "Show user profile", :path => "/users/", :version => '1.0 - 3.4.2012'
|
14
|
+
# param :id, Fixnum, :desc => "User ID", :required => true
|
15
|
+
# desc <<-EOS
|
16
|
+
# Long description...
|
17
|
+
# EOS
|
18
|
+
def resource_description(options = {}, &block) #:doc:
|
19
|
+
return unless Apipie.active_dsl?
|
20
|
+
Apipie.remove_resource_description(self)
|
21
|
+
Apipie.define_resource_description(self, &block) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Declare an api.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
# api :GET, "/resource_route", "short description",
|
28
|
+
#
|
29
|
+
def api(method, path, desc = nil) #:doc:
|
30
|
+
return unless Apipie.active_dsl?
|
31
|
+
Apipie.add_method_description_args(method, path, desc)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Describe the next method.
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
# desc "print hello world"
|
38
|
+
# def hello_world
|
39
|
+
# puts "hello world"
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
def desc(description) #:doc:
|
43
|
+
return unless Apipie.active_dsl?
|
44
|
+
if Apipie.last_description
|
45
|
+
raise "Double method description."
|
46
|
+
end
|
47
|
+
Apipie.last_description = description
|
48
|
+
end
|
49
|
+
alias :description :desc
|
50
|
+
|
51
|
+
# Reference other similar method
|
52
|
+
#
|
53
|
+
# api :PUT, '/articles/:id'
|
54
|
+
# see "articles#create"
|
55
|
+
# def update; end
|
56
|
+
def see(method_key)
|
57
|
+
return unless Apipie.active_dsl?
|
58
|
+
raise "'See' method called twice." if Apipie.last_see
|
59
|
+
Apipie.last_see = method_key
|
60
|
+
end
|
61
|
+
|
62
|
+
# Show some example of what does the described
|
63
|
+
# method return.
|
64
|
+
def example(example) #:doc:
|
65
|
+
return unless Apipie.active_dsl?
|
66
|
+
Apipie.add_example(example)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Describe possible errors
|
70
|
+
#
|
71
|
+
# Example:
|
72
|
+
# error :desc => "speaker is sleeping", :code => 500
|
73
|
+
# error 500, "speaker is sleeping"
|
74
|
+
# def hello_world
|
75
|
+
# return 500 if self.speaker.sleeping?
|
76
|
+
# puts "hello world"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
def error(*args) #:doc:
|
80
|
+
return unless Apipie.active_dsl?
|
81
|
+
Apipie.last_errors << Apipie::ErrorDescription.new(args)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Describe method's parameter
|
85
|
+
#
|
86
|
+
# Example:
|
87
|
+
# param :greeting, String, :desc => "arbitrary text", :required => true
|
88
|
+
# def hello_world(greeting)
|
89
|
+
# puts greeting
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
def param(param_name, *args, &block) #:doc:
|
93
|
+
return unless Apipie.active_dsl?
|
94
|
+
Apipie.last_params << Apipie::ParamDescription.new(param_name, *args, &block)
|
95
|
+
end
|
96
|
+
|
97
|
+
# create method api and redefine newly added method
|
98
|
+
def method_added(method_name) #:doc:
|
99
|
+
super
|
100
|
+
|
101
|
+
return unless Apipie.active_dsl?
|
102
|
+
return unless Apipie.apipie_provided?
|
103
|
+
|
104
|
+
# remove method description if exists and create new one
|
105
|
+
Apipie.remove_method_description(self, method_name)
|
106
|
+
description = Apipie.define_method_description(self, method_name)
|
107
|
+
|
108
|
+
# redefine method only if validation is turned on
|
109
|
+
if Apipie.configuration.validate == true
|
110
|
+
|
111
|
+
old_method = instance_method(method_name)
|
112
|
+
|
113
|
+
define_method(method_name) do |*args|
|
114
|
+
|
115
|
+
if Apipie.configuration.validate == true
|
116
|
+
description.params.each do |_, param|
|
117
|
+
|
118
|
+
# check if required parameters are present
|
119
|
+
if param.required && !params.has_key?(param.name)
|
120
|
+
raise ArgumentError.new("Expecting #{param.name} parameter.")
|
121
|
+
end
|
122
|
+
|
123
|
+
# params validations
|
124
|
+
if params.has_key?(param.name)
|
125
|
+
param.validate(params[:"#{param.name}"])
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# run the original method code
|
132
|
+
old_method.bind(self).call(*args)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end # def method_added
|
138
|
+
end # module DSL
|
139
|
+
end # module Apipie
|