praxis 0.11.2 → 0.13.0
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 +4 -4
- data/CHANGELOG.md +24 -0
- data/lib/api_browser/app/js/controllers/action.js +2 -2
- data/lib/api_browser/app/js/controllers/type.js +2 -2
- data/lib/praxis/action_definition.rb +11 -0
- data/lib/praxis/api_definition.rb +2 -0
- data/lib/praxis/bootloader_stages/environment.rb +1 -0
- data/lib/praxis/controller.rb +2 -11
- data/lib/praxis/media_type.rb +12 -3
- data/lib/praxis/media_type_collection.rb +0 -2
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +27 -5
- data/lib/praxis/request_stages/request_stage.rb +53 -32
- data/lib/praxis/request_stages/response.rb +2 -3
- data/lib/praxis/resource_definition.rb +11 -1
- data/lib/praxis/responses/http.rb +108 -20
- data/lib/praxis/responses/internal_server_error.rb +1 -1
- data/lib/praxis/responses/validation_error.rb +1 -1
- data/lib/praxis/restful_doc_generator.rb +27 -3
- data/lib/praxis/router.rb +16 -2
- data/lib/praxis/skeletor/restful_routing_config.rb +3 -0
- data/lib/praxis/stage.rb +1 -1
- data/lib/praxis/tasks/api_docs.rb +1 -1
- data/lib/praxis/tasks/console.rb +21 -3
- data/lib/praxis/tasks/routes.rb +19 -7
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +3 -5
- data/spec/functional_spec.rb +12 -0
- data/spec/praxis/action_definition_spec.rb +17 -0
- data/spec/praxis/media_type_spec.rb +22 -2
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +62 -15
- data/spec/praxis/request_stage_spec.rb +147 -67
- data/spec/praxis/resource_definition_spec.rb +18 -2
- data/spec/praxis/restful_routing_config_spec.rb +1 -1
- data/spec/praxis/router_spec.rb +115 -37
- data/spec/spec_app/design/resources/instances.rb +1 -1
- data/spec/support/spec_media_types.rb +2 -0
- metadata +8 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4684312c88071162f3525b9ee7c88c9f9a7587d2
|
4
|
+
data.tar.gz: fcf53c832ebc5f430dc37b9944ccc334b7ec3678
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a600f9e9857b338f87c3dbec975e016a7f3bee940b0a9c590cfc241e7b05e81825877a92a6b49049089ef76ecabcf127ef978d3d545d828b8d7ce197a0b792d8
|
7
|
+
data.tar.gz: 115db171ee75c4569beab2277e4c917bcd768e444e264b769862373936365a54cff1eaa154c21cf7543b59816756e45aafddbc0dd0c95714afdc392f95cae006
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# praxis changelog
|
2
2
|
|
3
|
+
## next
|
4
|
+
|
5
|
+
## 0.13.0
|
6
|
+
|
7
|
+
* Added `nodoc!` method to `ActionDefinition`, `ResourceDefinition` to hide actions and resources from the generated documentation.
|
8
|
+
* Default HTTP responses:
|
9
|
+
* Added descriptions
|
10
|
+
* Added 408 RequestTimeout response
|
11
|
+
* Replaced Ruport dependency in `praxis:routes` rake task with TerminalTable.
|
12
|
+
* Fixed doc browser issue when attributes defaulting to false wouldn't display the default section.
|
13
|
+
* Enhanced several logging aspects of the PraxisMapper plugin:
|
14
|
+
* The log-level of the stats is now configurable in the plugin (see the comments [here](https://github.com/rightscale/praxis/blob/master/lib/praxis/plugins/praxis_mapper_plugin.rb) for details)
|
15
|
+
* Added a "silence_mapper_stats" attribute in the Request objects so, actions and/or controllers can selectively skip logging stats (for example, health check controllers, etc)
|
16
|
+
* It now logs a compact message (with the same heading) when the identity map has had no interactions.
|
17
|
+
* Added X-Cascade header support
|
18
|
+
* Configured with boolean `praxis.x_cascade` that defaults to true.
|
19
|
+
* When enabled, Praxis will add an 'X-Cascade: pass' header to the response when the request was not routable to an action. It is not added if the action explicitly returns a `NotFound` response.
|
20
|
+
* Fixed bug in request handling where `after` callbacks were being executed, even if the stage returned a response.
|
21
|
+
* Added a handy option to tie an action route to match any HTTP verb.
|
22
|
+
* Simply use `any` as the verb when you define it (i.e. any '/things/:id' )
|
23
|
+
* Allow a MediaType to define a custom `links` attribute like any other.
|
24
|
+
* This is not compatible if it also wants to use the `links` DSL.
|
25
|
+
|
26
|
+
|
3
27
|
## 0.11.2
|
4
28
|
|
5
29
|
* The Doc Browser will now not change the menu when refreshing.
|
@@ -18,8 +18,8 @@ app.controller("ActionCtrl", function($scope, $stateParams, Documentation) {
|
|
18
18
|
var example = set.example ? JSON.stringify(set.example[name], null, 2) : '';
|
19
19
|
if (!attribute.options) attribute.options = {};
|
20
20
|
if (example) attribute.options.example = example;
|
21
|
-
if (attribute.values) attribute.options.values = attribute.values;
|
22
|
-
if (attribute.default) attribute.options.default = attribute.default;
|
21
|
+
if (attribute.values != null) attribute.options.values = attribute.values;
|
22
|
+
if (attribute.default != null) attribute.options.default = attribute.default;
|
23
23
|
});
|
24
24
|
}
|
25
25
|
});
|
@@ -15,8 +15,8 @@
|
|
15
15
|
var example = JSON.stringify($scope.type.example[name], null, 2);
|
16
16
|
if (!attribute.options) attribute.options = {};
|
17
17
|
if (example) attribute.options.example = example;
|
18
|
-
if (attribute.values) attribute.options.values = attribute.values;
|
19
|
-
if (attribute.default) attribute.options.default = attribute.default;
|
18
|
+
if (attribute.values != null) attribute.options.values = attribute.values;
|
19
|
+
if (attribute.default != null) attribute.options.default = attribute.default;
|
20
20
|
});
|
21
21
|
|
22
22
|
Documentation.getIndex().success(function(response) {
|
@@ -16,6 +16,10 @@ module Praxis
|
|
16
16
|
attr_reader :named_routes
|
17
17
|
attr_reader :responses
|
18
18
|
|
19
|
+
# opaque hash of user-defined medata, used to decorate the definition,
|
20
|
+
# and also available in the generated JSON documents
|
21
|
+
attr_reader :metadata
|
22
|
+
|
19
23
|
class << self
|
20
24
|
attr_accessor :doc_decorations
|
21
25
|
end
|
@@ -30,6 +34,7 @@ module Praxis
|
|
30
34
|
@name = name
|
31
35
|
@resource_definition = resource_definition
|
32
36
|
@responses = Hash.new
|
37
|
+
@metadata = Hash.new
|
33
38
|
|
34
39
|
if (media_type = resource_definition.media_type)
|
35
40
|
if media_type.kind_of?(Class) && media_type < Praxis::MediaType
|
@@ -147,6 +152,7 @@ module Praxis
|
|
147
152
|
{}.tap do |hash|
|
148
153
|
hash[:description] = description
|
149
154
|
hash[:name] = name
|
155
|
+
hash[:metadata] = metadata
|
150
156
|
# FIXME: change to :routes along with api browser
|
151
157
|
hash[:urls] = routes.collect(&:describe)
|
152
158
|
hash[:headers] = headers.describe if headers
|
@@ -162,5 +168,10 @@ module Praxis
|
|
162
168
|
end
|
163
169
|
end
|
164
170
|
|
171
|
+
def nodoc!
|
172
|
+
metadata[:doc_visibility] = :none
|
173
|
+
end
|
174
|
+
|
175
|
+
|
165
176
|
end
|
166
177
|
end
|
@@ -46,11 +46,13 @@ module Praxis
|
|
46
46
|
api.response_template :ok do |media_type: |
|
47
47
|
media_type media_type
|
48
48
|
status 200
|
49
|
+
description 'Standard response for successful HTTP requests.'
|
49
50
|
end
|
50
51
|
|
51
52
|
api.response_template :created do |location: nil|
|
52
53
|
location location
|
53
54
|
status 201
|
55
|
+
description 'The request has been fulfilled and resulted in a new resource being created.'
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
data/lib/praxis/controller.rb
CHANGED
@@ -4,6 +4,7 @@ require 'active_support/all'
|
|
4
4
|
module Praxis
|
5
5
|
module Controller
|
6
6
|
extend ::ActiveSupport::Concern
|
7
|
+
|
7
8
|
# A Controller always requires the callbacks
|
8
9
|
include Praxis::Callbacks
|
9
10
|
|
@@ -11,6 +12,7 @@ module Praxis
|
|
11
12
|
attr_reader :request
|
12
13
|
attr_accessor :response
|
13
14
|
end
|
15
|
+
|
14
16
|
module ClassMethods
|
15
17
|
def implements(definition)
|
16
18
|
define_singleton_method(:definition) do
|
@@ -27,16 +29,5 @@ module Praxis
|
|
27
29
|
@response = response
|
28
30
|
end
|
29
31
|
|
30
|
-
# def request
|
31
|
-
# @request
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# def response
|
35
|
-
# @response
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# def response=(value)
|
39
|
-
# @response = value
|
40
|
-
# end
|
41
32
|
end
|
42
33
|
end
|
data/lib/praxis/media_type.rb
CHANGED
@@ -30,11 +30,20 @@ module Praxis
|
|
30
30
|
super(opts.merge(dsl_compiler: MediaType::DSLCompiler), &block)
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
33
|
+
def self._finalize!
|
34
|
+
super
|
35
|
+
if @attribute && self.attributes.key?(:links) && self.attributes[:links].type < Praxis::Links
|
36
|
+
# Only define out special links accessor if it was setup using the special DSL
|
37
|
+
# (we might have an app defining an attribute called `links` on its own, in which
|
38
|
+
# case we leave it be)
|
39
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
40
|
+
def links
|
41
|
+
self.class::Links.new(@object)
|
42
|
+
end
|
43
|
+
RUBY
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
|
-
|
38
47
|
end
|
39
48
|
|
40
49
|
end
|
@@ -36,6 +36,7 @@ require 'terminal-table'
|
|
36
36
|
# output into the Praxis::Application.instance.logger app log. Possible
|
37
37
|
# values are: "detailed", "short", and "skip" (i.e. do not print the stats
|
38
38
|
# at all).
|
39
|
+
# 3. stats_log_level: the logging level with which the statistics should be logged.
|
39
40
|
#
|
40
41
|
# See http://praxis-framework.io/reference/plugins/ for further details on how
|
41
42
|
# to use a plugin and pass it options.
|
@@ -75,6 +76,7 @@ module Praxis
|
|
75
76
|
def prepare_config!(node)
|
76
77
|
node.attributes do
|
77
78
|
attribute :log_stats, String, values: ['detailed', 'short', 'skip'], default: 'detailed'
|
79
|
+
attribute :stats_log_level, Symbol, values: [:fatal,:error,:warn,:info,:debug], default: :info
|
78
80
|
attribute :repositories, Attributor::Hash.of(key: String, value: RepositoryConfig)
|
79
81
|
end
|
80
82
|
end
|
@@ -103,7 +105,7 @@ module Praxis
|
|
103
105
|
unless log_stats == 'skip'
|
104
106
|
Praxis::Notifications.subscribe 'praxis.request.all' do |name, *junk, payload|
|
105
107
|
if (identity_map = payload[:request].identity_map)
|
106
|
-
PraxisMapperPlugin::Statistics.log(identity_map, log_stats)
|
108
|
+
PraxisMapperPlugin::Statistics.log(payload[:request], identity_map, log_stats)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
end
|
@@ -126,6 +128,15 @@ module Praxis
|
|
126
128
|
def identity_map=(map)
|
127
129
|
@identity_map = map
|
128
130
|
end
|
131
|
+
|
132
|
+
def silence_mapper_stats
|
133
|
+
@silence_mapper_stats
|
134
|
+
end
|
135
|
+
|
136
|
+
def silence_mapper_stats=(value)
|
137
|
+
@silence_mapper_stats = value
|
138
|
+
end
|
139
|
+
|
129
140
|
end
|
130
141
|
|
131
142
|
module Controller
|
@@ -133,15 +144,22 @@ module Praxis
|
|
133
144
|
|
134
145
|
included do
|
135
146
|
before :action do |controller|
|
136
|
-
controller.request.identity_map = Praxis::Mapper::IdentityMap.
|
147
|
+
controller.request.identity_map = Praxis::Mapper::IdentityMap.new
|
137
148
|
end
|
138
149
|
end
|
139
150
|
end
|
140
151
|
|
141
152
|
module Statistics
|
142
153
|
|
143
|
-
def self.log(identity_map, log_stats)
|
154
|
+
def self.log(request, identity_map, log_stats)
|
144
155
|
return if identity_map.nil?
|
156
|
+
return if request.silence_mapper_stats == true
|
157
|
+
if identity_map.queries.empty?
|
158
|
+
self.to_logger "No database interactions observed."
|
159
|
+
return
|
160
|
+
end
|
161
|
+
|
162
|
+
|
145
163
|
case log_stats
|
146
164
|
when 'detailed'
|
147
165
|
self.detailed(identity_map)
|
@@ -187,7 +205,7 @@ module Praxis
|
|
187
205
|
table.align_column(3, :right)
|
188
206
|
table.align_column(4, :right)
|
189
207
|
table.align_column(5, :right)
|
190
|
-
|
208
|
+
self.to_logger "\n#{table.to_s}"
|
191
209
|
end
|
192
210
|
|
193
211
|
def self.round_fields_at(values, indices)
|
@@ -197,7 +215,11 @@ module Praxis
|
|
197
215
|
end
|
198
216
|
|
199
217
|
def self.short(identity_map)
|
200
|
-
|
218
|
+
self.to_logger identity_map.query_statistics.sum_totals.to_s
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.to_logger(message)
|
222
|
+
Praxis::Application.instance.logger.__send__(Plugin.instance.config.stats_log_level, "Praxis::Mapper Statistics: #{message}")
|
201
223
|
end
|
202
224
|
end
|
203
225
|
end
|
@@ -15,68 +15,89 @@ module Praxis
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def execute_controller_callbacks(callbacks)
|
18
|
-
if callbacks.
|
18
|
+
if callbacks.key?(path)
|
19
19
|
callbacks[path].each do |(conditions, block)|
|
20
|
-
if conditions.
|
20
|
+
if conditions.key?(:actions)
|
21
21
|
next unless conditions[:actions].include? action.name
|
22
22
|
end
|
23
23
|
result = block.call(controller)
|
24
|
-
|
24
|
+
if result && result.kind_of?(Praxis::Response)
|
25
|
+
controller.response = result
|
26
|
+
return result
|
27
|
+
end
|
25
28
|
end
|
26
29
|
end
|
30
|
+
|
27
31
|
nil
|
28
32
|
end
|
29
|
-
|
33
|
+
|
30
34
|
def run
|
31
35
|
setup!
|
32
36
|
setup_deferred_callbacks!
|
33
|
-
|
37
|
+
|
38
|
+
# stage-level callbacks (typically empty) will never shortcut
|
34
39
|
execute_callbacks(self.before_callbacks)
|
35
|
-
|
40
|
+
|
36
41
|
r = execute_controller_callbacks(controller.class.before_callbacks)
|
42
|
+
# Shortcut lifecycle if filters return non-nil value
|
43
|
+
# (which should only be a Response)
|
37
44
|
return r if r
|
38
45
|
|
39
46
|
result = execute_with_around
|
40
|
-
#
|
47
|
+
# Shortcut lifecycle if filters return a response
|
48
|
+
# (non-nil but non-response-class response is ignored)
|
49
|
+
if result && result.kind_of?(Praxis::Response)
|
50
|
+
controller.response = result
|
51
|
+
return result
|
52
|
+
end
|
53
|
+
|
41
54
|
r = execute_controller_callbacks(controller.class.after_callbacks)
|
42
|
-
|
43
|
-
|
55
|
+
# Shortcut lifecycle if filters return non-nil value
|
56
|
+
# (which should only be a Response)
|
57
|
+
return r if r
|
58
|
+
|
59
|
+
# stage-level callbacks (typically empty) will never shortcut
|
60
|
+
execute_callbacks(self.after_callbacks)
|
44
61
|
|
45
62
|
result
|
46
63
|
end
|
47
64
|
|
48
65
|
def execute_with_around
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
66
|
+
cb = controller.class.around_callbacks[ path ]
|
67
|
+
if cb == nil || cb.empty?
|
68
|
+
execute
|
69
|
+
else
|
70
|
+
inner_proc = proc { execute }
|
71
|
+
|
72
|
+
applicable = cb.select do |(conditions, handler)|
|
73
|
+
if conditions.has_key?(:actions)
|
74
|
+
(conditions[:actions].include? action.name) ? true : false
|
75
|
+
else
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
chain = applicable.reverse.inject(inner_proc) do |blk, (conditions, handler)|
|
81
|
+
if blk
|
82
|
+
proc{ handler.call(controller,blk) }
|
83
|
+
else
|
84
|
+
proc{ handler.call }
|
61
85
|
end
|
62
|
-
|
63
|
-
chain = applicable.reverse.inject(inner_proc) do |blk, (conditions, handler)|
|
64
|
-
if blk
|
65
|
-
proc{ handler.call(controller,blk) }
|
66
|
-
else
|
67
|
-
proc{ handler.call }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
chain.call
|
71
86
|
end
|
87
|
+
chain.call
|
88
|
+
end
|
72
89
|
end
|
73
|
-
|
90
|
+
|
91
|
+
|
74
92
|
def execute
|
75
93
|
raise NotImplementedError, 'Subclass must implement Stage#execute' unless @stages.any?
|
76
94
|
|
77
95
|
@stages.each do |stage|
|
78
96
|
shortcut = stage.run
|
79
|
-
|
97
|
+
if shortcut && shortcut.kind_of?(Praxis::Response)
|
98
|
+
controller.response = shortcut
|
99
|
+
return shortcut
|
100
|
+
end
|
80
101
|
end
|
81
102
|
nil
|
82
103
|
end
|
@@ -2,12 +2,11 @@ module Praxis
|
|
2
2
|
module RequestStages
|
3
3
|
|
4
4
|
class Response < RequestStage
|
5
|
-
WHITELIST_RESPONSES = [:validation_error]
|
5
|
+
WHITELIST_RESPONSES = [:validation_error]
|
6
6
|
|
7
7
|
def execute
|
8
8
|
response = controller.response
|
9
9
|
|
10
|
-
|
11
10
|
unless action.responses.include?(response.response_name) || WHITELIST_RESPONSES.include?(response.response_name)
|
12
11
|
raise Exceptions::InvalidResponse.new(
|
13
12
|
"Response #{response.name.inspect} is not allowed for #{action.name.inspect}"
|
@@ -21,7 +20,7 @@ module Praxis
|
|
21
20
|
end
|
22
21
|
rescue Exceptions::Validation => e
|
23
22
|
controller.response = Responses::ValidationError.new(exception: e)
|
24
|
-
retry
|
23
|
+
retry
|
25
24
|
end
|
26
25
|
|
27
26
|
end
|
@@ -12,6 +12,7 @@ module Praxis
|
|
12
12
|
@responses = Hash.new
|
13
13
|
@action_defaults = []
|
14
14
|
@version_options = {}
|
15
|
+
@metadata = {}
|
15
16
|
Application.instance.resource_definitions << self
|
16
17
|
end
|
17
18
|
|
@@ -20,7 +21,11 @@ module Praxis
|
|
20
21
|
attr_reader :routing_config
|
21
22
|
attr_reader :responses
|
22
23
|
attr_reader :version_options
|
23
|
-
|
24
|
+
|
25
|
+
# opaque hash of user-defined medata, used to decorate the definition,
|
26
|
+
# and also available in the generated JSON documents
|
27
|
+
attr_reader :metadata
|
28
|
+
|
24
29
|
attr_accessor :controller
|
25
30
|
|
26
31
|
# FIXME: this is inconsistent with the rest of the magic DSL convention.
|
@@ -94,6 +99,7 @@ module Praxis
|
|
94
99
|
hash[:description] = description
|
95
100
|
hash[:media_type] = media_type.name if media_type
|
96
101
|
hash[:actions] = actions.values.map(&:describe)
|
102
|
+
hash[:metadata] = metadata
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
@@ -104,6 +110,10 @@ module Praxis
|
|
104
110
|
self.instance_eval(&ApiDefinition.instance.traits[trait_name])
|
105
111
|
end
|
106
112
|
|
113
|
+
def nodoc!
|
114
|
+
metadata[:doc_visibility] = :none
|
115
|
+
end
|
116
|
+
|
107
117
|
end
|
108
118
|
|
109
119
|
end
|
@@ -2,34 +2,37 @@ module Praxis
|
|
2
2
|
|
3
3
|
module Responses
|
4
4
|
|
5
|
-
#
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# In a
|
5
|
+
# Descriptions from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
6
|
+
|
7
|
+
# Standard response for successful HTTP requests.
|
8
|
+
# The actual response will depend on the request method used.
|
9
|
+
# In a GET request, the response will contain an entity
|
10
|
+
# corresponding to the requested resource.
|
11
|
+
# In a POST request the response will contain an entity
|
10
12
|
# describing or containing the result of the action.
|
11
13
|
class Ok < Praxis::Response
|
12
14
|
self.status = 200
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
# The request has been fulfilled and resulted in a new resource
|
17
|
+
# The request has been fulfilled and resulted in a new resource
|
17
18
|
# being created.
|
18
19
|
class Created < Praxis::Response
|
19
20
|
self.status = 201
|
20
21
|
end
|
21
22
|
|
22
23
|
|
23
|
-
# The request has been accepted for processing, but the
|
24
|
-
# processing has not been completed. The request might or might
|
25
|
-
# not eventually be acted upon, as it might be disallowed when
|
24
|
+
# The request has been accepted for processing, but the
|
25
|
+
# processing has not been completed. The request might or might
|
26
|
+
# not eventually be acted upon, as it might be disallowed when
|
26
27
|
# processing actually takes place.
|
27
28
|
class Accepted < Praxis::Response
|
28
29
|
self.status = 202
|
29
30
|
end
|
30
31
|
|
31
32
|
|
32
|
-
# The server successfully processed the request, but is not
|
33
|
+
# The server successfully processed the request, but is not
|
34
|
+
# returning any content. Usually used as a response to
|
35
|
+
# a successful delete request.
|
33
36
|
class NoContent < Praxis::Response
|
34
37
|
self.status = 204
|
35
38
|
end
|
@@ -101,11 +104,15 @@ module Praxis
|
|
101
104
|
end
|
102
105
|
|
103
106
|
|
104
|
-
#
|
107
|
+
# The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.
|
105
108
|
class NotAcceptable < Praxis::Response
|
106
109
|
self.status = 406
|
107
110
|
end
|
108
111
|
|
112
|
+
# The server timed out waiting for the request.
|
113
|
+
class RequestTimeout < Praxis::Response
|
114
|
+
self.status = 408
|
115
|
+
end
|
109
116
|
|
110
117
|
# 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.
|
111
118
|
class Conflict < Praxis::Response
|
@@ -124,19 +131,100 @@ module Praxis
|
|
124
131
|
self.status = 422
|
125
132
|
end
|
126
133
|
|
127
|
-
|
128
134
|
ApiDefinition.define do |api|
|
129
|
-
self.constants.each do |class_name|
|
130
|
-
response_class = self.const_get(class_name)
|
131
|
-
response_name = response_class.response_name
|
132
|
-
next if api.responses.key?(response_name)
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
-
|
136
|
+
api.response_template :accepted do
|
137
|
+
status 202
|
138
|
+
description "The request has been accepted for processing, but the processing has not been completed."
|
139
|
+
end
|
140
|
+
|
141
|
+
api.response_template :no_content do
|
142
|
+
status 204
|
143
|
+
description "The server successfully processed the request, but is not returning any content."
|
144
|
+
end
|
145
|
+
|
146
|
+
api.response_template :multiple_choices do
|
147
|
+
status 300
|
148
|
+
description "Indicates multiple options for the resource that the client may follow."
|
149
|
+
end
|
150
|
+
|
151
|
+
api.response_template :moved_permanently do
|
152
|
+
status 301
|
153
|
+
description "This and all future requests should be directed to the given URI."
|
154
|
+
end
|
155
|
+
|
156
|
+
api.response_template :found do
|
157
|
+
status 302
|
158
|
+
description "The requested resource resides temporarily under a different URI."
|
159
|
+
end
|
160
|
+
|
161
|
+
api.response_template :see_other do
|
162
|
+
status 303
|
163
|
+
description "The response to the request can be found under another URI using a GET method"
|
164
|
+
end
|
165
|
+
|
166
|
+
api.response_template :not_modified do
|
167
|
+
status 304
|
168
|
+
description "Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-Match."
|
169
|
+
end
|
170
|
+
|
171
|
+
api.response_template :temporary_redirect do
|
172
|
+
status 307
|
173
|
+
description "In this case, the request should be repeated with another URI; however, future requests should still use the original URI."
|
174
|
+
end
|
175
|
+
|
176
|
+
api.response_template :bad_request do
|
177
|
+
status 400
|
178
|
+
description "The request cannot be fulfilled due to bad syntax."
|
179
|
+
end
|
180
|
+
|
181
|
+
api.response_template :unauthorized do
|
182
|
+
status 401
|
183
|
+
description "Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."
|
184
|
+
end
|
185
|
+
|
186
|
+
api.response_template :forbidden do
|
187
|
+
status 403
|
188
|
+
description "The request was a valid request, but the server is refusing to respond to it."
|
189
|
+
end
|
190
|
+
|
191
|
+
api.response_template :not_found do
|
192
|
+
status 404
|
193
|
+
description "The requested resource could not be found but may be available again in the future."
|
194
|
+
end
|
195
|
+
|
196
|
+
api.response_template :method_not_allowed do
|
197
|
+
status 405
|
198
|
+
description "A request was made of a resource using a request method not supported by that resource."
|
199
|
+
end
|
200
|
+
|
201
|
+
api.response_template :not_acceptable do
|
202
|
+
status 406
|
203
|
+
description "The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."
|
204
|
+
end
|
205
|
+
|
206
|
+
api.response_template :request_timeout do
|
207
|
+
status 408
|
208
|
+
description "The server timed out waiting for the request."
|
209
|
+
end
|
210
|
+
|
211
|
+
api.response_template :conflict do
|
212
|
+
status 409
|
213
|
+
description "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."
|
214
|
+
end
|
215
|
+
|
216
|
+
api.response_template :precondition_failed do
|
217
|
+
status 412
|
218
|
+
description "The server does not meet one of the preconditions that the requester put on the request."
|
219
|
+
end
|
137
220
|
|
221
|
+
api.response_template :unprocessable_entity do
|
222
|
+
status 422
|
223
|
+
description "The request was well-formed but was unable to be followed due to semantic errors."
|
138
224
|
end
|
225
|
+
|
139
226
|
end
|
140
227
|
|
228
|
+
|
141
229
|
end
|
142
230
|
end
|
@@ -36,7 +36,7 @@ module Praxis
|
|
36
36
|
|
37
37
|
ApiDefinition.define do |api|
|
38
38
|
api.response_template :internal_server_error do
|
39
|
-
description "
|
39
|
+
description "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."
|
40
40
|
status 500
|
41
41
|
media_type "application/json"
|
42
42
|
end
|
@@ -31,7 +31,7 @@ module Praxis
|
|
31
31
|
|
32
32
|
ApiDefinition.define do |api|
|
33
33
|
api.response_template :validation_error do
|
34
|
-
description "
|
34
|
+
description "An error message indicating that one or more elements of the request did not match the API specification for the action"
|
35
35
|
status 400
|
36
36
|
media_type "application/json"
|
37
37
|
end
|