praxis 0.15.0 → 0.16.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 +28 -2
- data/lib/api_browser/Gruntfile.js +6 -1
- data/lib/praxis.rb +2 -14
- data/lib/praxis/action_definition.rb +45 -16
- data/lib/praxis/api_definition.rb +36 -17
- data/lib/praxis/api_general_info.rb +59 -16
- data/lib/praxis/request_stages/request_stage.rb +2 -6
- data/lib/praxis/resource_definition.rb +50 -17
- data/lib/praxis/router.rb +10 -11
- data/lib/praxis/routing_config.rb +65 -0
- data/lib/praxis/tasks/routes.rb +8 -4
- data/lib/praxis/trait.rb +107 -0
- data/lib/praxis/types/media_type_common.rb +1 -1
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +1 -1
- data/spec/functional_spec.rb +16 -3
- data/spec/praxis/action_definition_spec.rb +107 -5
- data/spec/praxis/api_definition_spec.rb +67 -44
- data/spec/praxis/api_general_info_spec.rb +28 -14
- data/spec/praxis/media_type_spec.rb +33 -6
- data/spec/praxis/resource_definition_spec.rb +46 -12
- data/spec/praxis/router_spec.rb +9 -15
- data/spec/praxis/routing_config_spec.rb +89 -0
- data/spec/praxis/trait_spec.rb +38 -0
- data/spec/spec_app/app/controllers/instances.rb +6 -2
- data/spec/spec_app/design/resources/instances.rb +19 -10
- data/spec/spec_app/design/resources/volumes.rb +3 -3
- data/spec/support/spec_resource_definitions.rb +11 -6
- data/tasks/thor/example.rb +43 -35
- metadata +8 -6
- data/lib/praxis/skeletor/restful_routing_config.rb +0 -55
- data/spec/praxis/restful_routing_config_spec.rb +0 -101
data/tasks/thor/example.rb
CHANGED
@@ -4,10 +4,10 @@ module PraxisGen
|
|
4
4
|
include Thor::Actions
|
5
5
|
|
6
6
|
namespace "praxis:example"
|
7
|
-
|
7
|
+
|
8
8
|
argument :app_name, required: true
|
9
9
|
desc "new", "Generates a new 'hello world' example application under an <app_name> directory"
|
10
|
-
|
10
|
+
|
11
11
|
def new
|
12
12
|
puts "GENERATION COMMENCED!! (for #{app_name})"
|
13
13
|
# Fix weird symbols in the app name (if they are)
|
@@ -33,12 +33,18 @@ module PraxisGen
|
|
33
33
|
puts " bundle exec rackup"
|
34
34
|
puts
|
35
35
|
puts " # terminal 2:"
|
36
|
-
puts "
|
37
|
-
puts " curl -i http://localhost:8888/api/hello
|
38
|
-
puts "
|
36
|
+
puts " # Index: list the hello words (especifying api version through the query string) "
|
37
|
+
puts " curl -i 'http://localhost:8888/api/hello?api_version=1.0' -H 'Authorization: Bearer XYZ' "
|
38
|
+
puts ""
|
39
|
+
puts " # Show: list one of the hello words (especifying api version through a header) "
|
40
|
+
puts " curl -i 'http://localhost:8888/api/hello/1' -H 'X-Api-Version: 1.0' -H 'Authorization: Bearer XYZ'"
|
41
|
+
puts ""
|
42
|
+
puts " # NotFound: Hello word will not be found under API 2.0"
|
43
|
+
puts " curl -i 'http://localhost:8888/api/hello/1' -H 'X-Api-Version: 2.0' -H 'Authorization: Bearer XYZ'"
|
44
|
+
puts " #Note: The Authorization header is made required in the application to emulate OAuth2 (but not used)"
|
39
45
|
nil
|
40
46
|
end
|
41
|
-
private
|
47
|
+
private
|
42
48
|
# Returns relative path for the new application
|
43
49
|
#
|
44
50
|
# @return [String]
|
@@ -51,8 +57,8 @@ private
|
|
51
57
|
def app_dir_pathname
|
52
58
|
@app_dir_pathname ||= Pathname.new(app_name)
|
53
59
|
end
|
54
|
-
|
55
|
-
|
60
|
+
|
61
|
+
|
56
62
|
# Returns path string built from the set of the given strings
|
57
63
|
#
|
58
64
|
# @param [String,Array] strings
|
@@ -65,8 +71,8 @@ private
|
|
65
71
|
def path(*strings)
|
66
72
|
app_dir_pathname.join(*strings).to_s
|
67
73
|
end
|
68
|
-
|
69
|
-
|
74
|
+
|
75
|
+
|
70
76
|
# Creates './config/environment.rb' file
|
71
77
|
#
|
72
78
|
# @return [void]
|
@@ -100,8 +106,8 @@ RUBY
|
|
100
106
|
end
|
101
107
|
nil
|
102
108
|
end
|
103
|
-
|
104
|
-
|
109
|
+
|
110
|
+
|
105
111
|
# Creates './Gemfile' file
|
106
112
|
#
|
107
113
|
# @return [void]
|
@@ -122,8 +128,8 @@ RUBY
|
|
122
128
|
end
|
123
129
|
nil
|
124
130
|
end
|
125
|
-
|
126
|
-
|
131
|
+
|
132
|
+
|
127
133
|
# Creates './Rakefile' file
|
128
134
|
#
|
129
135
|
# @return [void]
|
@@ -137,8 +143,8 @@ RUBY
|
|
137
143
|
end
|
138
144
|
nil
|
139
145
|
end
|
140
|
-
|
141
|
-
|
146
|
+
|
147
|
+
|
142
148
|
# Creates './config.ru' file
|
143
149
|
#
|
144
150
|
# @return [void]
|
@@ -160,8 +166,8 @@ RUBY
|
|
160
166
|
end
|
161
167
|
nil
|
162
168
|
end
|
163
|
-
|
164
|
-
|
169
|
+
|
170
|
+
|
165
171
|
def generate_app_definitions_hello_world
|
166
172
|
create_file path('design/api.rb') do
|
167
173
|
<<-RUBY
|
@@ -173,15 +179,16 @@ RUBY
|
|
173
179
|
# media_type media_type
|
174
180
|
# end
|
175
181
|
Praxis::ApiDefinition.define do
|
176
|
-
|
182
|
+
# Trait that when included will require a Bearer authorization header to be passed in.
|
183
|
+
trait :authorized do
|
177
184
|
headers do
|
178
|
-
key "
|
185
|
+
key "Authorization", String, regexp: /^.*Bearer\s/, required: true
|
179
186
|
end
|
180
187
|
end
|
181
188
|
end
|
182
189
|
RUBY
|
183
190
|
end
|
184
|
-
|
191
|
+
|
185
192
|
create_file path('design/resources/hello.rb') do
|
186
193
|
<<-RUBY
|
187
194
|
module V1
|
@@ -192,21 +199,23 @@ module V1
|
|
192
199
|
media_type V1::MediaTypes::Hello
|
193
200
|
version '1.0'
|
194
201
|
|
195
|
-
|
196
|
-
|
202
|
+
prefix '/api/hello'
|
203
|
+
|
204
|
+
# Will apply to all actions of this resource
|
205
|
+
trait :authorized
|
206
|
+
|
207
|
+
action_defaults do
|
208
|
+
response :ok
|
197
209
|
end
|
198
210
|
|
199
211
|
action :index do
|
200
|
-
use :versionable
|
201
212
|
|
202
213
|
routing do
|
203
214
|
get ''
|
204
215
|
end
|
205
|
-
response :ok
|
206
216
|
end
|
207
217
|
|
208
218
|
action :show do
|
209
|
-
use :versionable
|
210
219
|
|
211
220
|
routing do
|
212
221
|
get '/:id'
|
@@ -214,7 +223,6 @@ module V1
|
|
214
223
|
params do
|
215
224
|
attribute :id, Integer, required: true, min: 0
|
216
225
|
end
|
217
|
-
response :ok
|
218
226
|
response :not_found
|
219
227
|
end
|
220
228
|
end
|
@@ -222,19 +230,19 @@ module V1
|
|
222
230
|
end
|
223
231
|
RUBY
|
224
232
|
end
|
225
|
-
|
233
|
+
|
226
234
|
create_file path('design/media_types/hello.rb') do
|
227
235
|
<<-RUBY
|
228
236
|
module V1
|
229
237
|
module MediaTypes
|
230
238
|
class Hello < Praxis::MediaType
|
231
|
-
|
239
|
+
|
232
240
|
identifier 'application/json'
|
233
|
-
|
241
|
+
|
234
242
|
attributes do
|
235
243
|
attribute :string, String
|
236
244
|
end
|
237
|
-
|
245
|
+
|
238
246
|
view :default do
|
239
247
|
attribute :string
|
240
248
|
end
|
@@ -244,8 +252,8 @@ RUBY
|
|
244
252
|
RUBY
|
245
253
|
end
|
246
254
|
end
|
247
|
-
|
248
|
-
|
255
|
+
|
256
|
+
|
249
257
|
def generate_app_controllers_hello_world
|
250
258
|
create_file path('app/controllers/hello.rb') do
|
251
259
|
<<-RUBY
|
@@ -268,7 +276,7 @@ module V1
|
|
268
276
|
if hello
|
269
277
|
response.body = { id: id, data: hello }
|
270
278
|
else
|
271
|
-
self.response = Praxis::Responses::NotFound.new
|
279
|
+
self.response = Praxis::Responses::NotFound.new(body: "Hello word with index \#{id} not found in our DB")
|
272
280
|
end
|
273
281
|
response.headers['Content-Type'] = 'application/json'
|
274
282
|
response
|
@@ -278,6 +286,6 @@ end
|
|
278
286
|
RUBY
|
279
287
|
end
|
280
288
|
end
|
281
|
-
|
289
|
+
|
282
290
|
end
|
283
291
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: praxis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Blanquer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-04-
|
12
|
+
date: 2015-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -73,14 +73,14 @@ dependencies:
|
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '3.
|
76
|
+
version: '3.4'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '3.
|
83
|
+
version: '3.4'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: praxis-blueprints
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -878,8 +878,8 @@ files:
|
|
878
878
|
- lib/praxis/restful_doc_generator.rb
|
879
879
|
- lib/praxis/route.rb
|
880
880
|
- lib/praxis/router.rb
|
881
|
+
- lib/praxis/routing_config.rb
|
881
882
|
- lib/praxis/simple_media_type.rb
|
882
|
-
- lib/praxis/skeletor/restful_routing_config.rb
|
883
883
|
- lib/praxis/stage.rb
|
884
884
|
- lib/praxis/stats.rb
|
885
885
|
- lib/praxis/tasks.rb
|
@@ -887,6 +887,7 @@ files:
|
|
887
887
|
- lib/praxis/tasks/console.rb
|
888
888
|
- lib/praxis/tasks/environment.rb
|
889
889
|
- lib/praxis/tasks/routes.rb
|
890
|
+
- lib/praxis/trait.rb
|
890
891
|
- lib/praxis/types/media_type_common.rb
|
891
892
|
- lib/praxis/types/multipart.rb
|
892
893
|
- lib/praxis/version.rb
|
@@ -924,11 +925,12 @@ files:
|
|
924
925
|
- spec/praxis/response_spec.rb
|
925
926
|
- spec/praxis/responses/internal_server_error_spec.rb
|
926
927
|
- spec/praxis/responses/validation_error_spec.rb
|
927
|
-
- spec/praxis/restful_routing_config_spec.rb
|
928
928
|
- spec/praxis/route_spec.rb
|
929
929
|
- spec/praxis/router_spec.rb
|
930
|
+
- spec/praxis/routing_config_spec.rb
|
930
931
|
- spec/praxis/stage_spec.rb
|
931
932
|
- spec/praxis/stats_spec.rb
|
933
|
+
- spec/praxis/trait_spec.rb
|
932
934
|
- spec/praxis/types/collection_spec.rb
|
933
935
|
- spec/praxis/types/multipart_spec.rb
|
934
936
|
- spec/spec_app/app/concerns/authenticated.rb
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Praxis
|
2
|
-
module Skeletor
|
3
|
-
class RestfulRoutingConfig
|
4
|
-
|
5
|
-
attr_reader :name, :resource_definition, :routes
|
6
|
-
|
7
|
-
def initialize(name, resource_definition, &block)
|
8
|
-
@name = name
|
9
|
-
@resource_definition = resource_definition
|
10
|
-
@routes = []
|
11
|
-
|
12
|
-
@version_prefix = ""
|
13
|
-
if resource_definition.version_options
|
14
|
-
version_using = Array(resource_definition.version_options[:using])
|
15
|
-
if version_using.include?(:path)
|
16
|
-
@version_prefix = "#{Praxis::Request::path_version_prefix}#{resource_definition.version}"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
prefix( "/" + resource_definition.name.split("::").last.underscore )
|
20
|
-
|
21
|
-
if resource_definition.routing_config
|
22
|
-
instance_eval(&resource_definition.routing_config)
|
23
|
-
end
|
24
|
-
|
25
|
-
instance_eval(&block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def prefix(prefix=nil)
|
29
|
-
@path_prefix = prefix if prefix
|
30
|
-
@version_prefix + @path_prefix
|
31
|
-
end
|
32
|
-
|
33
|
-
def options(path, opts={}) add_route 'OPTIONS', path, opts end
|
34
|
-
def get(path, opts={}) add_route 'GET', path, opts end
|
35
|
-
def head(path, opts={}) add_route 'HEAD', path, opts end
|
36
|
-
def post(path, opts={}) add_route 'POST', path, opts end
|
37
|
-
def put(path, opts={}) add_route 'PUT', path, opts end
|
38
|
-
def delete(path, opts={}) add_route 'DELETE', path, opts end
|
39
|
-
def trace(path, opts={}) add_route 'TRACE', path, opts end
|
40
|
-
def connect(path, opts={}) add_route 'CONNECT', path, opts end
|
41
|
-
def patch(path, opts={}) add_route 'PATCH', path, opts end
|
42
|
-
def any(path, opts={}) add_route 'ANY', path, opts end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
def add_route(verb, path, options={})
|
47
|
-
path = Mustermann.new(prefix + path)
|
48
|
-
|
49
|
-
@routes << Route.new(verb, path, resource_definition.version, **options)
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Praxis::Skeletor::RestfulRoutingConfig do
|
4
|
-
|
5
|
-
let(:resource_definition) do
|
6
|
-
Class.new do
|
7
|
-
include Praxis::ResourceDefinition
|
8
|
-
def self.name; 'MyResource'; end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:action_name) { :index }
|
13
|
-
let(:routing_block) { Proc.new{} }
|
14
|
-
let(:default_route_prefix) { "/" + resource_definition.name.split("::").last.underscore }
|
15
|
-
|
16
|
-
subject(:routing_config){ Praxis::Skeletor::RestfulRoutingConfig.new(action_name, resource_definition, &routing_block) }
|
17
|
-
|
18
|
-
context "#initialize" do
|
19
|
-
it "name" do
|
20
|
-
expect(subject.name).to eq(:index)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "resource_definition" do
|
24
|
-
expect(subject.resource_definition).to eq(resource_definition)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "routes" do
|
28
|
-
expect(subject.routes.empty?).to eq(true)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "prefix without path version" do
|
32
|
-
expect(subject.prefix).to eq(default_route_prefix)
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'prefix using path version' do
|
36
|
-
let(:resource_definition) do
|
37
|
-
Class.new do
|
38
|
-
include Praxis::ResourceDefinition
|
39
|
-
version "1.0", using: :path
|
40
|
-
def self.name; 'MyVersionedResource'; end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
it "prefix" do
|
44
|
-
expect(subject.prefix).to eq("/v1.0#{default_route_prefix}")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context "#add_route" do
|
50
|
-
let(:route_verb){ 'GET' }
|
51
|
-
let(:route_path){ '/path' }
|
52
|
-
let(:route_opts){ {option: 1} }
|
53
|
-
|
54
|
-
before(:each) do
|
55
|
-
routing_config.add_route(route_verb, route_path, route_opts)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "routes" do
|
59
|
-
expect(subject.routes.length).to eq(1)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "saves the verb and options into the route" do
|
63
|
-
route = subject.routes.first
|
64
|
-
|
65
|
-
expect(route.verb).to eq(route_verb)
|
66
|
-
expect(route.options).to eq(route_opts)
|
67
|
-
end
|
68
|
-
|
69
|
-
context "with a resource definition that does not have a route prefix" do
|
70
|
-
it 'saves the path with the default path prefix' do
|
71
|
-
path = subject.routes.first.path.to_s
|
72
|
-
expect(path).to eq(default_route_prefix + route_path)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context "with a resource definition that has a route prefix" do
|
77
|
-
let(:routing_block) { Proc.new{ prefix "/my_custom_route" } }
|
78
|
-
subject(:routing_config){ Praxis::Skeletor::RestfulRoutingConfig.new(action_name, resource_definition, &routing_block) }
|
79
|
-
it 'appends the prefix to the path' do
|
80
|
-
path = subject.routes.first.path.to_s
|
81
|
-
expect(path).to eq("/my_custom_route" + route_path)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
context 'route helpers' do
|
88
|
-
let(:route_prefix) { nil }
|
89
|
-
|
90
|
-
it 'call the add_route with the correct parameters' do
|
91
|
-
helper_verbs = [:get, :put, :post, :delete, :head, :options, :patch, :any]
|
92
|
-
helper_verbs.each do |verb|
|
93
|
-
path = "/path_for_#{verb}"
|
94
|
-
options = {option: verb}
|
95
|
-
expect(subject).to receive(:add_route).with(verb.to_s.upcase,path,options)
|
96
|
-
subject.__send__(verb, path, options)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|