praxis 0.21 → 0.22.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +20 -12
- data/CHANGELOG.md +24 -0
- data/CONTRIBUTING.md +4 -4
- data/README.md +11 -9
- data/lib/api_browser/app/js/directives/attribute_table.js +2 -1
- data/lib/api_browser/app/js/directives/conditional_requirements.js +13 -0
- data/lib/api_browser/app/js/directives/type_placeholder.js +10 -1
- data/lib/api_browser/app/js/factories/normalize_attributes.js +4 -2
- data/lib/api_browser/app/js/factories/template_for.js +5 -2
- data/lib/api_browser/app/js/filters/has_requirement.js +14 -0
- data/lib/api_browser/app/js/filters/tag_requirement.js +13 -0
- data/lib/api_browser/app/sass/praxis.scss +11 -0
- data/lib/api_browser/app/views/action.html +2 -2
- data/lib/api_browser/app/views/directives/attribute_description/member_options.html +2 -2
- data/lib/api_browser/app/views/directives/attribute_table.html +1 -1
- data/lib/api_browser/app/views/type.html +1 -1
- data/lib/api_browser/app/views/type/details.html +2 -2
- data/lib/api_browser/app/views/types/embedded/array.html +2 -0
- data/lib/api_browser/app/views/types/embedded/default.html +3 -1
- data/lib/api_browser/app/views/types/embedded/requirements.html +6 -0
- data/lib/api_browser/app/views/types/embedded/single_req.html +9 -0
- data/lib/api_browser/app/views/types/embedded/struct.html +14 -2
- data/lib/api_browser/app/views/types/standalone/array.html +1 -1
- data/lib/api_browser/app/views/types/standalone/struct.html +2 -1
- data/lib/api_browser/package.json +1 -1
- data/lib/praxis.rb +8 -6
- data/lib/praxis/action_definition.rb +9 -7
- data/lib/praxis/api_definition.rb +44 -27
- data/lib/praxis/api_general_info.rb +3 -2
- data/lib/praxis/application.rb +139 -20
- data/lib/praxis/bootloader.rb +2 -4
- data/lib/praxis/bootloader_stages/environment.rb +0 -13
- data/lib/praxis/controller.rb +2 -0
- data/lib/praxis/dispatcher.rb +16 -10
- data/lib/praxis/docs/generator.rb +20 -9
- data/lib/praxis/docs/link_builder.rb +1 -1
- data/lib/praxis/error_handler.rb +5 -5
- data/lib/praxis/extensions/attribute_filtering.rb +28 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +180 -0
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +273 -0
- data/lib/praxis/extensions/attribute_filtering/query_builder.rb +39 -0
- data/lib/praxis/extensions/field_selection.rb +3 -0
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +57 -0
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +65 -0
- data/lib/praxis/extensions/rails_compat.rb +2 -0
- data/lib/praxis/extensions/rails_compat/request_methods.rb +19 -0
- data/lib/praxis/extensions/rendering.rb +1 -1
- data/lib/praxis/file_group.rb +1 -1
- data/lib/praxis/middleware_app.rb +26 -6
- data/lib/praxis/multipart/parser.rb +14 -2
- data/lib/praxis/multipart/part.rb +5 -3
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +2 -2
- data/lib/praxis/plugins/rails_plugin.rb +104 -0
- data/lib/praxis/request.rb +8 -9
- data/lib/praxis/request_stages/response.rb +3 -2
- data/lib/praxis/request_superclassing.rb +11 -0
- data/lib/praxis/resource_definition.rb +14 -10
- data/lib/praxis/response.rb +6 -7
- data/lib/praxis/response_definition.rb +7 -5
- data/lib/praxis/response_template.rb +4 -3
- data/lib/praxis/responses/http.rb +0 -36
- data/lib/praxis/responses/internal_server_error.rb +3 -12
- data/lib/praxis/responses/multipart_ok.rb +4 -11
- data/lib/praxis/responses/validation_error.rb +1 -10
- data/lib/praxis/router.rb +3 -3
- data/lib/praxis/tasks/api_docs.rb +10 -2
- data/lib/praxis/tasks/routes.rb +1 -0
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +4 -5
- data/spec/functional_spec.rb +4 -6
- data/spec/praxis/action_definition_spec.rb +26 -15
- data/spec/praxis/api_definition_spec.rb +13 -8
- data/spec/praxis/api_general_info_spec.rb +3 -8
- data/spec/praxis/application_spec.rb +13 -7
- data/spec/praxis/middleware_app_spec.rb +24 -10
- data/spec/praxis/request_spec.rb +17 -7
- data/spec/praxis/request_stages/validate_spec.rb +1 -1
- data/spec/praxis/resource_definition_spec.rb +12 -10
- data/spec/praxis/response_definition_spec.rb +22 -5
- data/spec/praxis/response_spec.rb +12 -5
- data/spec/praxis/responses/internal_server_error_spec.rb +4 -7
- data/spec/praxis/responses/validation_error_spec.rb +2 -2
- data/spec/praxis/router_spec.rb +8 -4
- data/spec/spec_app/config.ru +1 -6
- data/spec/spec_helper.rb +3 -3
- data/tasks/thor/templates/generator/empty_app/Gemfile +3 -3
- metadata +36 -32
- data/.ruby-version +0 -1
- data/lib/praxis/stats.rb +0 -113
- data/spec/praxis/stats_spec.rb +0 -9
data/lib/praxis/request.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Praxis
|
|
2
2
|
|
|
3
|
-
class Request
|
|
4
|
-
attr_reader :env, :query
|
|
3
|
+
class Request < Praxis.request_superclass
|
|
4
|
+
attr_reader :env, :query, :praxis_instance
|
|
5
5
|
attr_accessor :route_params, :action
|
|
6
6
|
|
|
7
7
|
PATH_VERSION_PREFIX = "/v".freeze
|
|
@@ -14,10 +14,11 @@ module Praxis
|
|
|
14
14
|
API_NO_VERSION_NAME = 'n/a'.freeze
|
|
15
15
|
VERSION_USING_DEFAULTS = [:header, :params].freeze
|
|
16
16
|
|
|
17
|
-
def initialize(env)
|
|
17
|
+
def initialize(env, args={})
|
|
18
18
|
@env = env
|
|
19
19
|
@query = Rack::Utils.parse_nested_query(env[QUERY_STRING_NAME])
|
|
20
20
|
@route_params = {}
|
|
21
|
+
@praxis_instance = args[:application]
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# Determine the content type of this request as indicated by the Content-Type header.
|
|
@@ -86,8 +87,8 @@ module Praxis
|
|
|
86
87
|
PATH_VERSION_MATCHER = %r{^#{self.path_version_prefix}(?<version>[^\/]+)\/}.freeze
|
|
87
88
|
|
|
88
89
|
def path_version_matcher
|
|
89
|
-
if
|
|
90
|
-
matcher = Mustermann.new(
|
|
90
|
+
if praxis_instance.versioning_scheme == :path
|
|
91
|
+
matcher = Mustermann.new(praxis_instance.api_definition.info.base_path + '*')
|
|
91
92
|
matcher.params(self.path)[API_VERSION_PARAM_NAME]
|
|
92
93
|
else
|
|
93
94
|
PATH_VERSION_MATCHER.match(self.path)[:version]
|
|
@@ -96,8 +97,7 @@ module Praxis
|
|
|
96
97
|
|
|
97
98
|
def version
|
|
98
99
|
result = nil
|
|
99
|
-
|
|
100
|
-
Array(Application.instance.versioning_scheme).find do |mode|
|
|
100
|
+
Array(praxis_instance.versioning_scheme).find do |mode|
|
|
101
101
|
case mode
|
|
102
102
|
when :header;
|
|
103
103
|
result = env[API_VERSION_HEADER_NAME]
|
|
@@ -128,8 +128,7 @@ module Praxis
|
|
|
128
128
|
def load_payload(context)
|
|
129
129
|
return unless action.payload
|
|
130
130
|
return if content_type.nil?
|
|
131
|
-
|
|
132
|
-
raw = if (handler = Praxis::Application.instance.handlers[content_type.handler_name])
|
|
131
|
+
raw = if (handler = praxis_instance.handlers[content_type.handler_name])
|
|
133
132
|
handler.parse(self.raw_payload)
|
|
134
133
|
else
|
|
135
134
|
# TODO is this a good default?
|
|
@@ -8,8 +8,9 @@ module Praxis
|
|
|
8
8
|
|
|
9
9
|
response.handle
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
config = Application.current_instance.config
|
|
12
|
+
if config.praxis.validate_responses == true
|
|
13
|
+
validate_body = config.praxis.validate_response_bodies
|
|
13
14
|
|
|
14
15
|
response.validate(action, validate_body: validate_body)
|
|
15
16
|
end
|
|
@@ -8,11 +8,15 @@ module Praxis
|
|
|
8
8
|
DEFAULT_RESOURCE_HREF_ACTION = :show
|
|
9
9
|
|
|
10
10
|
included do
|
|
11
|
+
# Store the attached (i.e., current) Praxis App instance into the resource definition for easy retrieval later
|
|
12
|
+
@application = Application.instance
|
|
13
|
+
@application.resource_definitions << self
|
|
14
|
+
|
|
11
15
|
@version = 'n/a'.freeze
|
|
12
16
|
@actions = Hash.new
|
|
13
17
|
@responses = Hash.new
|
|
14
18
|
|
|
15
|
-
@action_defaults = Trait.new &ResourceDefinition.generate_defaults_block
|
|
19
|
+
@action_defaults = Trait.new &ResourceDefinition.generate_defaults_block(application: @application)
|
|
16
20
|
|
|
17
21
|
@version_options = {}
|
|
18
22
|
@metadata = {}
|
|
@@ -33,13 +37,12 @@ module Praxis
|
|
|
33
37
|
|
|
34
38
|
@on_finalize = Array.new
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
def self.generate_defaults_block( version: nil )
|
|
40
|
-
|
|
43
|
+
def self.generate_defaults_block( version: nil, application:)
|
|
41
44
|
# Ensure we inherit any base params defined in the API definition for the passed in version
|
|
42
|
-
base_attributes = if (base_params =
|
|
45
|
+
base_attributes = if (base_params = application.api_definition.info(version).base_params)
|
|
43
46
|
base_params.attributes
|
|
44
47
|
else
|
|
45
48
|
{}
|
|
@@ -56,8 +59,8 @@ module Praxis
|
|
|
56
59
|
end
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
def self.finalize!
|
|
60
|
-
|
|
62
|
+
def self.finalize!(application: )
|
|
63
|
+
application.resource_definitions.each do |resource_definition|
|
|
61
64
|
while (block = resource_definition.on_finalize.shift)
|
|
62
65
|
block.call
|
|
63
66
|
end
|
|
@@ -73,6 +76,7 @@ module Praxis
|
|
|
73
76
|
attr_reader :traits
|
|
74
77
|
attr_reader :version_prefix
|
|
75
78
|
attr_reader :parent_prefix
|
|
79
|
+
attr_reader :application
|
|
76
80
|
|
|
77
81
|
# opaque hash of user-defined medata, used to decorate the definition,
|
|
78
82
|
# and also available in the generated JSON documents
|
|
@@ -199,7 +203,7 @@ module Praxis
|
|
|
199
203
|
end
|
|
200
204
|
end
|
|
201
205
|
|
|
202
|
-
@action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version )
|
|
206
|
+
@action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version, application: self.application)
|
|
203
207
|
end
|
|
204
208
|
|
|
205
209
|
|
|
@@ -238,10 +242,10 @@ module Praxis
|
|
|
238
242
|
end
|
|
239
243
|
|
|
240
244
|
def trait(trait_name)
|
|
241
|
-
unless
|
|
245
|
+
unless self.application.api_definition.traits.has_key? trait_name
|
|
242
246
|
raise Exceptions::InvalidTrait.new("Trait #{trait_name} not found in the system")
|
|
243
247
|
end
|
|
244
|
-
trait =
|
|
248
|
+
trait = self.application.api_definition.traits.fetch(trait_name)
|
|
245
249
|
@traits << trait_name
|
|
246
250
|
end
|
|
247
251
|
alias_method :use, :trait
|
data/lib/praxis/response.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Praxis
|
|
|
18
18
|
klass.status = self.status if self.status
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def initialize(status:self.class.status, headers:{}, body:
|
|
21
|
+
def initialize(status:self.class.status, headers:{}, body: nil, location: nil)
|
|
22
22
|
@name = response_name
|
|
23
23
|
@status = status
|
|
24
24
|
@headers = headers
|
|
@@ -63,24 +63,23 @@ module Praxis
|
|
|
63
63
|
self.class.response_name
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def format!
|
|
66
|
+
def format!(config:)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
def encode!
|
|
69
|
+
def encode!(handlers:)
|
|
70
70
|
case @body
|
|
71
71
|
when Hash, Array
|
|
72
72
|
# response payload is structured data; transform it into an entity using the handler
|
|
73
73
|
# implied by the response's media type. If no handler is registered for this
|
|
74
74
|
# name, assume JSON as a default handler.
|
|
75
|
-
handlers = Praxis::Application.instance.handlers
|
|
76
75
|
handler = (content_type && handlers[content_type.handler_name]) || handlers['json']
|
|
77
76
|
@body = handler.generate(@body)
|
|
78
77
|
end
|
|
79
78
|
end
|
|
80
79
|
|
|
81
|
-
def finish
|
|
82
|
-
format!
|
|
83
|
-
encode!
|
|
80
|
+
def finish(application:)
|
|
81
|
+
format!(config: application.config)
|
|
82
|
+
encode!(handlers: application.handlers)
|
|
84
83
|
|
|
85
84
|
@body = Array(@body)
|
|
86
85
|
|
|
@@ -4,8 +4,9 @@ module Praxis
|
|
|
4
4
|
|
|
5
5
|
class ResponseDefinition
|
|
6
6
|
attr_reader :name
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
attr_reader :application
|
|
8
|
+
|
|
9
|
+
def initialize(response_name, application, **spec, &block)
|
|
9
10
|
unless response_name
|
|
10
11
|
raise Exceptions::InvalidConfiguration.new(
|
|
11
12
|
"Response name is required for a response specification"
|
|
@@ -13,6 +14,7 @@ module Praxis
|
|
|
13
14
|
end
|
|
14
15
|
@spec = { headers:{} }
|
|
15
16
|
@name = response_name
|
|
17
|
+
@application = application
|
|
16
18
|
self.instance_exec(**spec, &block) if block_given?
|
|
17
19
|
|
|
18
20
|
if self.status.nil?
|
|
@@ -141,9 +143,9 @@ module Praxis
|
|
|
141
143
|
# FIXME: remove load when when MediaTypeCommon.identifier returns a MediaTypeIdentifier
|
|
142
144
|
identifier = MediaTypeIdentifier.load(self.media_type.identifier)
|
|
143
145
|
|
|
144
|
-
default_handlers =
|
|
146
|
+
default_handlers = application.api_definition.info.produces
|
|
145
147
|
|
|
146
|
-
handlers =
|
|
148
|
+
handlers = application.handlers.select do |k,v|
|
|
147
149
|
default_handlers.include?(k)
|
|
148
150
|
end
|
|
149
151
|
|
|
@@ -200,7 +202,7 @@ module Praxis
|
|
|
200
202
|
raise ArgumentError, "Parts definition for response #{name} does not allow :like and a block simultaneously"
|
|
201
203
|
end
|
|
202
204
|
if like
|
|
203
|
-
template =
|
|
205
|
+
template = application.api_definition.response(like)
|
|
204
206
|
@parts = template.compile(nil, **args)
|
|
205
207
|
else # block
|
|
206
208
|
@parts = Praxis::ResponseDefinition.new('anonymous', **args, &a_proc)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
module Praxis
|
|
2
2
|
|
|
3
3
|
class ResponseTemplate
|
|
4
|
-
attr_reader :name, :block
|
|
4
|
+
attr_reader :name, :block, :application
|
|
5
5
|
|
|
6
|
-
def initialize(response_name, &block)
|
|
6
|
+
def initialize(response_name, application, &block)
|
|
7
7
|
@name = response_name
|
|
8
8
|
@block = block
|
|
9
|
+
@application = application
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def compile(action=nil, **args)
|
|
@@ -23,7 +24,7 @@ module Praxis
|
|
|
23
24
|
args[:media_type] = media_type
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
|
-
Praxis::ResponseDefinition.new(name, **args, &block)
|
|
27
|
+
Praxis::ResponseDefinition.new(name, application, **args, &block)
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def describe
|
|
@@ -131,41 +131,5 @@ module Praxis
|
|
|
131
131
|
self.status = 422
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
ApiDefinition.define do |api|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
[
|
|
138
|
-
[ :accepted, 202, "The request has been accepted for processing, but the processing has not been completed." ],
|
|
139
|
-
[ :no_content, 204,"The server successfully processed the request, but is not returning any content."],
|
|
140
|
-
[ :multiple_choices, 300,"Indicates multiple options for the resource that the client may follow."],
|
|
141
|
-
[ :moved_permanently, 301,"This and all future requests should be directed to the given URI."],
|
|
142
|
-
[ :found, 302,"The requested resource resides temporarily under a different URI."],
|
|
143
|
-
[ :see_other, 303,"The response to the request can be found under another URI using a GET method"],
|
|
144
|
-
[ :not_modified, 304,"Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-Match."],
|
|
145
|
-
[ :temporary_redirect, 307,"In this case, the request should be repeated with another URI; however, future requests should still use the original URI."],
|
|
146
|
-
[ :bad_request, 400,"The request cannot be fulfilled due to bad syntax."],
|
|
147
|
-
[ :unauthorized, 401,"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."],
|
|
148
|
-
[ :forbidden, 403,"The request was a valid request, but the server is refusing to respond to it."],
|
|
149
|
-
[ :not_found, 404,"The requested resource could not be found but may be available again in the future."],
|
|
150
|
-
[ :method_not_allowed, 405,"A request was made of a resource using a request method not supported by that resource."],
|
|
151
|
-
[ :not_acceptable, 406,"The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."],
|
|
152
|
-
[ :request_timeout, 408,"The server timed out waiting for the request."],
|
|
153
|
-
[ :conflict, 409, "Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates."],
|
|
154
|
-
[ :precondition_failed, 412,"The server does not meet one of the preconditions that the requester put on the request."],
|
|
155
|
-
[ :unprocessable_entity, 422,"The request was well-formed but was unable to be followed due to semantic errors."],
|
|
156
|
-
].each do |name, code, base_description|
|
|
157
|
-
api.response_template name do |media_type: nil, location: nil, headers: nil, description: nil|
|
|
158
|
-
status code
|
|
159
|
-
description( description || base_description ) # description can "potentially" be overriden in an individual action.
|
|
160
|
-
|
|
161
|
-
media_type media_type if media_type
|
|
162
|
-
location location if location
|
|
163
|
-
headers headers if headers
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
|
|
170
134
|
end
|
|
171
135
|
end
|
|
@@ -13,16 +13,15 @@ module Praxis
|
|
|
13
13
|
@error = error
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def format!(exception = @error)
|
|
16
|
+
def format!(exception = @error, config:)
|
|
17
17
|
if @error
|
|
18
|
-
|
|
19
|
-
if Application.instance.config.praxis.show_exceptions == true
|
|
18
|
+
if config.praxis.show_exceptions == true
|
|
20
19
|
msg = {
|
|
21
20
|
name: exception.class.name,
|
|
22
21
|
message: exception.message,
|
|
23
22
|
backtrace: exception.backtrace
|
|
24
23
|
}
|
|
25
|
-
msg[:cause] = format!(exception.cause) if exception.cause
|
|
24
|
+
msg[:cause] = format!(exception.cause, config: config) if exception.cause
|
|
26
25
|
else
|
|
27
26
|
msg = {name: 'InternalServerError', message: "Something bad happened."}
|
|
28
27
|
end
|
|
@@ -34,12 +33,4 @@ module Praxis
|
|
|
34
33
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
ApiDefinition.define do |api|
|
|
38
|
-
api.response_template :internal_server_error do
|
|
39
|
-
description "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."
|
|
40
|
-
status 500
|
|
41
|
-
media_type "application/json"
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
36
|
end
|
|
@@ -19,7 +19,7 @@ module Praxis
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def encode!
|
|
22
|
+
def encode!(handlers:)
|
|
23
23
|
case @body
|
|
24
24
|
when Praxis::Types::MultipartArray
|
|
25
25
|
@body = @body.dump
|
|
@@ -28,9 +28,9 @@ module Praxis
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def finish
|
|
32
|
-
format!
|
|
33
|
-
encode!
|
|
31
|
+
def finish(application:)
|
|
32
|
+
format!(config: application.config)
|
|
33
|
+
encode!(handlers: application.handlers)
|
|
34
34
|
|
|
35
35
|
@body = Array(@body)
|
|
36
36
|
|
|
@@ -41,11 +41,4 @@ module Praxis
|
|
|
41
41
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
ApiDefinition.define do |api|
|
|
45
|
-
api.response_template :multipart_ok do |media_type: Praxis::Types::MultipartArray|
|
|
46
|
-
status 200
|
|
47
|
-
media_type media_type
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
44
|
end
|
|
@@ -15,7 +15,7 @@ module Praxis
|
|
|
15
15
|
@documentation = documentation
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def format!
|
|
18
|
+
def format!(**_args)
|
|
19
19
|
@body = {name: 'ValidationError', summary: @summary }
|
|
20
20
|
@body[:errors] = @errors if @errors
|
|
21
21
|
|
|
@@ -31,13 +31,4 @@ module Praxis
|
|
|
31
31
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
ApiDefinition.define do |api|
|
|
36
|
-
api.response_template :validation_error do
|
|
37
|
-
description "An error message indicating that one or more elements of the request did not match the API specification for the action"
|
|
38
|
-
status 400
|
|
39
|
-
media_type "application/json"
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
34
|
end
|
data/lib/praxis/router.rb
CHANGED
|
@@ -50,7 +50,7 @@ module Praxis
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def add_route(target, route)
|
|
53
|
-
path_versioning = (
|
|
53
|
+
path_versioning = (application.versioning_scheme == :path)
|
|
54
54
|
|
|
55
55
|
# DEPRECATED: remove with ResourceDefinition.version using: :path
|
|
56
56
|
path_versioning ||= (target.action.resource_definition.version_options[:using] == :path)
|
|
@@ -65,7 +65,7 @@ module Praxis
|
|
|
65
65
|
def call(env_or_request)
|
|
66
66
|
request = case env_or_request
|
|
67
67
|
when Hash
|
|
68
|
-
request_class.new(env_or_request)
|
|
68
|
+
request_class.new(env_or_request, application: application)
|
|
69
69
|
when request_class
|
|
70
70
|
env_or_request
|
|
71
71
|
else
|
|
@@ -101,7 +101,7 @@ module Praxis
|
|
|
101
101
|
body += " Available versions = #{pretty_versions}."
|
|
102
102
|
end
|
|
103
103
|
headers = {"Content-Type" => "text/plain"}
|
|
104
|
-
if
|
|
104
|
+
if application.config.praxis.x_cascade
|
|
105
105
|
headers['X-Cascade'] = 'pass'
|
|
106
106
|
end
|
|
107
107
|
result = [404, headers, [body]]
|
|
@@ -58,8 +58,16 @@ namespace :praxis do
|
|
|
58
58
|
require 'fileutils'
|
|
59
59
|
|
|
60
60
|
Praxis::Blueprint.caching_enabled = false
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
|
|
62
|
+
apps = Praxis::Application.registered_apps
|
|
63
|
+
if apps.size == 1
|
|
64
|
+
# Backwards compatible directory generation when there's only 1 app
|
|
65
|
+
Praxis::Docs::Generator.generate(Dir.pwd, name: apps.first[0], skip_sub_directory: true)
|
|
66
|
+
else
|
|
67
|
+
apps.each do|name,instance|
|
|
68
|
+
Praxis::Docs::Generator.generate(Dir.pwd, name: name)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
63
71
|
end
|
|
64
72
|
|
|
65
73
|
end
|
data/lib/praxis/tasks/routes.rb
CHANGED
data/lib/praxis/version.rb
CHANGED