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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/lib/api_browser/app/js/controllers/action.js +2 -2
  4. data/lib/api_browser/app/js/controllers/type.js +2 -2
  5. data/lib/praxis/action_definition.rb +11 -0
  6. data/lib/praxis/api_definition.rb +2 -0
  7. data/lib/praxis/bootloader_stages/environment.rb +1 -0
  8. data/lib/praxis/controller.rb +2 -11
  9. data/lib/praxis/media_type.rb +12 -3
  10. data/lib/praxis/media_type_collection.rb +0 -2
  11. data/lib/praxis/plugins/praxis_mapper_plugin.rb +27 -5
  12. data/lib/praxis/request_stages/request_stage.rb +53 -32
  13. data/lib/praxis/request_stages/response.rb +2 -3
  14. data/lib/praxis/resource_definition.rb +11 -1
  15. data/lib/praxis/responses/http.rb +108 -20
  16. data/lib/praxis/responses/internal_server_error.rb +1 -1
  17. data/lib/praxis/responses/validation_error.rb +1 -1
  18. data/lib/praxis/restful_doc_generator.rb +27 -3
  19. data/lib/praxis/router.rb +16 -2
  20. data/lib/praxis/skeletor/restful_routing_config.rb +3 -0
  21. data/lib/praxis/stage.rb +1 -1
  22. data/lib/praxis/tasks/api_docs.rb +1 -1
  23. data/lib/praxis/tasks/console.rb +21 -3
  24. data/lib/praxis/tasks/routes.rb +19 -7
  25. data/lib/praxis/version.rb +1 -1
  26. data/praxis.gemspec +3 -5
  27. data/spec/functional_spec.rb +12 -0
  28. data/spec/praxis/action_definition_spec.rb +17 -0
  29. data/spec/praxis/media_type_spec.rb +22 -2
  30. data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +62 -15
  31. data/spec/praxis/request_stage_spec.rb +147 -67
  32. data/spec/praxis/resource_definition_spec.rb +18 -2
  33. data/spec/praxis/restful_routing_config_spec.rb +1 -1
  34. data/spec/praxis/router_spec.rb +115 -37
  35. data/spec/spec_app/design/resources/instances.rb +1 -1
  36. data/spec/support/spec_media_types.rb +2 -0
  37. metadata +8 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: faa4c7b780be253c8aa05ac8f9969d2d9754efbf
4
- data.tar.gz: 4b71e46c0337fc3c6346ca6d1da68512155d0712
3
+ metadata.gz: 4684312c88071162f3525b9ee7c88c9f9a7587d2
4
+ data.tar.gz: fcf53c832ebc5f430dc37b9944ccc334b7ec3678
5
5
  SHA512:
6
- metadata.gz: 3914c19d0fdbc50d4aaa949dc0dfc4df0c8a602abd9313cc9c1bf12a17d73e667a024e2299b83d0f6b19697d808de5ab721d5089b36a658200979be680e78c6b
7
- data.tar.gz: f692e9d7e62f5fe2ed80899f1b0c63ecbf0b01ec987a95bf157f78b4a373583a07720063c04a3bfea486cafae89340e3686f3b2f95ca4c91a5e2976461a62230
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
 
@@ -43,6 +43,7 @@ module Praxis
43
43
  attribute :praxis do
44
44
  attribute :validate_responses, Attributor::Boolean, default: false
45
45
  attribute :show_exceptions, Attributor::Boolean, default: false
46
+ attribute :x_cascade, Attributor::Boolean, default: true
46
47
  end
47
48
  end
48
49
  end
@@ -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
@@ -30,11 +30,20 @@ module Praxis
30
30
  super(opts.merge(dsl_compiler: MediaType::DSLCompiler), &block)
31
31
  end
32
32
 
33
- def links
34
- self.class::Links.new(@object)
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
@@ -61,13 +61,11 @@ module Praxis
61
61
  members = []
62
62
  size = rand(3) + 1
63
63
 
64
-
65
64
  size.times do |i|
66
65
  subcontext = context + ["at(#{i})"]
67
66
  members << @member_attribute.example(subcontext)
68
67
  end
69
68
 
70
-
71
69
  result.object._members = members
72
70
  result
73
71
  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.setup!
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
- Praxis::Application.instance.logger.info "Praxis::Mapper Statistics:\n#{table.to_s}"
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
- Praxis::Application.instance.logger.info "Praxis::Mapper Statistics: #{identity_map.query_statistics.sum_totals.to_s}"
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.has_key?(path)
18
+ if callbacks.key?(path)
19
19
  callbacks[path].each do |(conditions, block)|
20
- if conditions.has_key?(:actions)
20
+ if conditions.key?(:actions)
21
21
  next unless conditions[:actions].include? action.name
22
22
  end
23
23
  result = block.call(controller)
24
- return result if result && result.kind_of?(Praxis::Response)
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
- # Shortcut lifecycle if filters return a response (non-nil but non-response-class response is ignored)
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
- # Still allow the after callbacks to shortcut it if necessary.
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
- return r if r
43
- execute_callbacks(self.after_callbacks)
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
- cb = controller.class.around_callbacks[ path ]
50
- if cb == nil || cb.empty?
51
- execute
52
- else
53
- inner_proc = proc { execute }
54
-
55
- applicable = cb.select do |(conditions, handler)|
56
- if conditions.has_key?(:actions)
57
- (conditions[:actions].include? action.name) ? true : false
58
- else
59
- true
60
- end
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
- return shortcut if shortcut && shortcut.kind_of?(Praxis::Response)
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
- # Standard response for successful HTTP requests.
6
- # The actual response will depend on the request method used.
7
- # In a GET request, the response will contain an entity
8
- # corresponding to the requested resource.
9
- # In a POST request the response will contain an entity
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 returning any content. Usually used as a response to a successful delete request.
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
- # A request was made of a resource using a request method not supported by that resource; for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.
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
- api.response_template response_name do
135
- status response_class.status
136
- end
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 "When an internal server error occurs..."
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 "When parameter validation hits..."
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