traim 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -9
  3. data/lib/traim.rb +121 -129
  4. data/test/resource.rb +20 -20
  5. data/traim.gemspec +1 -1
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f905b5beabf9f73c766a104fcf98618ff5849263
4
- data.tar.gz: ab123a3a6068bd2a45e9ffd1acbff56e6f22ee99
3
+ metadata.gz: ece137da93d77a125ef001c07c3d259e5ccb0128
4
+ data.tar.gz: dd4af9b6a0c3078182eaeb210c20faf17d427592
5
5
  SHA512:
6
- metadata.gz: 615d1dff8a603429d0f8e19259ef416fe838bf611ee94a3c40d6dc885300cf1c0a5b02393627163a39d6dfb5586dc5846fe8b09e19504e3aaa4d1078552058a5
7
- data.tar.gz: ffbe8f31ef7893f9463a8b03328bbcdc45d1471853b30243b8a5a90efe3d9a83011a899229450699a92d60f223168d0ed07242a3d4ea03e97c344c293a9ceb52
6
+ metadata.gz: a93dbdabe1d31e39e4b687de31e09d193e7b88f3e16f9a3283b5c7e8d55ec14bf19f96d0869cd18681d233eacdc7debb710a3bd2f2a38e396ac82e9e04452f34
7
+ data.tar.gz: 19dad77694405744df974cb015b5346f24bbf2a79b76af75b02655c2c038946a89c4ed3e44b6ddeb49dd4fb0bf1b4338b6f6445e3a22847fffbfe63667ccc63d
data/README.md CHANGED
@@ -69,8 +69,8 @@ Traim.application do
69
69
  attribute :id
70
70
  attribute :name
71
71
 
72
- action :show do |params|
73
- user = model.find_by_email params["payload"]["email"]
72
+ action :show do
73
+ user = model.find_by_email params["email"]
74
74
  user.name = "[admin] #{user.name}"
75
75
  user
76
76
  end
@@ -140,7 +140,7 @@ Traim.application do
140
140
  member :blurred do
141
141
 
142
142
  # GET /users/1/blurred
143
- show do |params|
143
+ show do
144
144
  record.name[1..2] = 'xx'
145
145
  record
146
146
  end
@@ -162,13 +162,13 @@ Traim.application do
162
162
  collection :admin do
163
163
 
164
164
  # GET /users/admin
165
- show do |params|
165
+ show do
166
166
  model.all
167
167
  end
168
168
 
169
169
  # POST /users/admin
170
- create do |params|
171
- model.create(params["payload"])
170
+ create do
171
+ model.create(params)
172
172
  end
173
173
  end
174
174
  end
@@ -223,10 +223,9 @@ Traim.application do
223
223
  attribute :id
224
224
  attribute :name
225
225
 
226
- action :show do |params|
226
+ action :show do
227
227
  auth(params["id"])
228
- model.find params["id"]
229
- user
228
+ record
230
229
  end
231
230
  end
232
231
  end
@@ -78,6 +78,11 @@ class Traim
78
78
  app = @applications[name] ||= Application.new(name)
79
79
  end
80
80
 
81
+ def show(&block); @resource.action(:show, &block) end
82
+ def create(&block); @resource.action(:create, &block) end
83
+ def update(&block); @resource.action(:update, &block) end
84
+ def destory(&block); @resource.action(:destory, &block) end
85
+
81
86
  def helpers(&block)
82
87
  @helpers_block = block
83
88
  end
@@ -91,124 +96,44 @@ class Traim
91
96
  if app = @applications[segment]
92
97
  app.route(request, seg)
93
98
  else
94
- router = Router.new(@resources)
95
- router.instance_eval(&@helpers_block) unless @helpers_block.nil?
96
- router.run(seg, inbox)
97
- router.render(request)
99
+ model = run(seg, inbox, request)
100
+ render(request, model)
98
101
  end
99
102
  end
100
103
 
101
- def compile(&block)
102
- logger.debug("Compile application: #{@name}")
103
- instance_eval(&block)
104
- end
105
- end
106
-
107
- class Error < StandardError
108
-
109
- def initialize(options = {})
110
- @message = options[:message] || error_message
111
- @body = options[:body] || error_message
112
- super(@message)
113
- end
114
-
115
- def status; 500 end
116
- def error_message; 'Internal Server Error' end
117
- def header; DEFAULT_HEADER end
118
- def body; {message: @body} end
119
- end
120
- class NotImplementedError < Error
121
- def error_message; "Not Implemented Error" end
122
- def status; 501 end
123
- end
124
- class BadRequestError < Error
125
- def error_message; "Bad Request Error" end
126
- def status; 400 end
127
- end
128
- class NotFoundError < Error
129
- def error_message; "Not Found Error" end
130
- def status; 404 end
131
- end
132
-
133
- class Router
134
-
135
- def status; @status || ok end
136
- def logger; Traim.logger end
137
-
138
- # status code sytax suger
139
- def ok; @status = 200 end
140
- def created; @status = 201 end
141
- def no_cotent; @status = 204 end
142
-
143
- def headers(key, value)
144
- @headers[key] = value
145
- end
146
-
147
- def initialize(resources)
148
- @status = nil
149
- @resources = resources
150
- @headers = {}
151
- end
152
-
153
- def self.resources; @resources ||= {} end
154
-
155
- def resources(name)
156
- @resources[name]
157
- end
158
-
159
- def show(&block); @resource.action(:show, &block) end
160
- def create(&block); @resource.action(:create, &block) end
161
- def update(&block); @resource.action(:update, &block) end
162
- def destory(&block); @resource.action(:destory, &block) end
163
-
164
- def run(seg, inbox)
104
+ def run(seg, inbox, request)
105
+ model = nil
165
106
  begin
166
107
  segment = inbox[:segment].to_sym
167
108
 
168
- if @resource.nil?
169
- raise BadRequestError unless @resource = resources(segment)
109
+ if model.nil?
110
+ raise BadRequestError unless @resource = @resources[segment]
111
+ model = Model.new(@resource.model, request)
170
112
  next
171
113
  end
172
114
 
173
- if @id.nil? && !defined?(@collection_name)
115
+ if model.id.nil?
174
116
  if collection = @resource.collections[segment]
175
- @collection_name = segment
176
- return instance_eval(&collection)
117
+ instance_eval(&collection)
118
+ break
177
119
  else
178
- @id = segment.to_s.to_i
179
- @record = @resource.model_delegator.show(@id)
120
+ model.id = segment.to_s.to_i
180
121
  next
181
122
  end
182
123
  end
183
124
 
184
- if !defined?(@member_name)
185
- if member = @resource.members[segment]
186
- @member_name = segment
187
- return instance_eval(&member)
188
- end
125
+ if member = @resource.members[segment]
126
+ instance_eval(&member)
127
+ break
189
128
  end
190
129
 
191
130
  raise BadRequestError
192
131
  end while seg.capture(:segment, inbox)
132
+
133
+ model.instance_eval(&@helpers_block) unless @helpers_block.nil?
134
+ model
193
135
  end
194
136
 
195
- def to_json
196
- if @result.kind_of?(ActiveRecord::Relation)
197
- hash = @result.map do |object|
198
- @resource.to_hash(object, @resources)
199
- end
200
- JSON.dump(hash)
201
- else
202
- new_hash = {}
203
- if @result.errors.size == 0
204
- new_hash = @resource.to_hash(@result, @resources)
205
- else
206
- new_hash = @result.errors.messages
207
- end
208
- JSON.dump(new_hash)
209
- end
210
- end
211
-
212
137
  def action(name)
213
138
  raise NotImplementedError unless action = @resource.actions[name]
214
139
 
@@ -219,43 +144,89 @@ class Traim
219
144
  def default_actions
220
145
  @default_actions ||= begin
221
146
  actions = {}
222
- delegator = @resource.model_delegator
223
- actions["POST"] = lambda do |params|
224
- delegator.create(params["payload"])
147
+ actions["POST"] = lambda do
148
+ create(params)
225
149
  end
226
- actions["GET"] = lambda do |params|
227
- delegator.show(params["id"])
150
+ actions["GET"] = lambda do
151
+ show(id)
228
152
  end
229
- actions["PUT"] = lambda do |params|
230
- result = delegator.update(params["id"], params["payload"])
153
+ actions["PUT"] = lambda do
154
+ result = update(id, params)
231
155
  result
232
156
  end
233
- actions["DELETE"] = lambda do |params|
234
- delegator.delete(@id)
157
+ actions["DELETE"] = lambda do
158
+ delete(id)
235
159
  end
236
160
  actions
237
161
  end
238
162
  end
239
163
 
240
- def model; @resource.model end
241
- def record; @record; end
164
+ def to_json(resources, model)
165
+ if @result.kind_of?(ActiveRecord::Relation)
166
+ hash = @result.map do |object|
167
+ @resource.to_hash(object, resources, model)
168
+ end
169
+ JSON.dump(hash)
170
+ else
171
+ new_hash = {}
172
+ if @result.errors.size == 0
173
+ new_hash = @resource.to_hash(@result, resources, model)
174
+ else
175
+ new_hash = @result.errors.messages
176
+ end
177
+ JSON.dump(new_hash)
178
+ end
179
+ end
242
180
 
243
- def render(request)
181
+ def render(request, model)
244
182
  method_block = action(request.request_method)
245
- payload = request.params
183
+
246
184
  if (method_block[:options][:permit])
247
- if not_permmited_payload = payload.detect { |key, value| !method_block[:options][:permit].include?(key) }
185
+ if not_permmited_payload = request.params.detect { |key, value| !method_block[:options][:permit].include?(key) }
248
186
  raise BadRequestError.new(message: "Not permitted payload: #{not_permmited_payload}")
249
187
  end
250
188
  end
251
- params = {"payload" => payload}
252
- params["id"] = @id unless @id.nil?
253
- @result = @resource.execute(params, &method_block[:block])
254
189
 
255
- [status, @headers, [to_json]]
190
+ model.params = request.params
191
+ @result = model.instance_eval(&method_block[:block])
192
+ [model.status, model.headers, [to_json(@resources, model)]]
193
+ end
194
+
195
+ def compile(&block)
196
+ logger.debug("Compile application: #{@name}")
197
+ instance_eval(&block)
256
198
  end
257
199
  end
258
200
 
201
+ class Error < StandardError
202
+ def initialize(options = {})
203
+ @message = options[:message] || error_message
204
+ @body = options[:body] || error_message
205
+ super(@message)
206
+ end
207
+
208
+ def status; 500 end
209
+ def error_message; 'Internal Server Error' end
210
+ def header; DEFAULT_HEADER end
211
+ def body; {message: @body} end
212
+ end
213
+ class NotImplementedError < Error
214
+ def error_message; "Not Implemented Error" end
215
+ def status; 501 end
216
+ end
217
+ class BadRequestError < Error
218
+ def error_message; "Bad Request Error" end
219
+ def status; 400 end
220
+ end
221
+ class ForbiddenError < Error
222
+ def error_message; "Forbidden Error" end
223
+ def status; 403 end
224
+ end
225
+ class NotFoundError < Error
226
+ def error_message; "Not Found Error" end
227
+ def status; 404 end
228
+ end
229
+
259
230
  class Resource
260
231
  ACTION_METHODS = {create: 'POST', show: 'GET', update: 'PUT', destory: 'DELETE'}
261
232
 
@@ -264,19 +235,11 @@ class Traim
264
235
  instance_eval(&block)
265
236
  end
266
237
 
267
- def execute(params, &block)
268
- yield params
269
- end
270
-
271
238
  def model(object = nil, options = {})
272
239
  @model = object unless object.nil?
273
240
  @model
274
241
  end
275
242
 
276
- def model_delegator
277
- @model_delegator ||= Model.new(model)
278
- end
279
-
280
243
  def actions; @actions ||= {} end
281
244
  def action(name, options = {}, &block)
282
245
  actions[ACTION_METHODS[name]] = {block: block, options: options}
@@ -314,7 +277,7 @@ class Traim
314
277
  fields << {name: name, type: 'connection'}
315
278
  end
316
279
 
317
- def to_hash(object, resources, nested_associations = [])
280
+ def to_hash(object, resources, model, nested_associations = [])
318
281
  return if object.nil?
319
282
 
320
283
  fields.inject({}) do | hash, attr|
@@ -323,20 +286,20 @@ class Traim
323
286
  if attr[:block].nil?
324
287
  object.attributes[name.to_s]
325
288
  else
326
- execute(object, &attr[:block])
289
+ model.instance_exec(object, &attr[:block])
327
290
  end
328
291
  elsif attr[:type] == 'association'
329
292
  raise Error if nested_associations.include?(name)
330
293
  nested_associations << name
331
294
  object.send(name).map do |association|
332
- resources[name].to_hash(association, resources, nested_associations.dup)
295
+ resources[name].to_hash(association, resources, model, nested_associations.dup)
333
296
  end
334
297
  else
335
298
  resource_name = name.to_s.pluralize.to_sym
336
299
  raise Error.new(message: "Inifinite Association") if nested_associations.include?(resource_name)
337
300
  raise Error if object.class.reflections[name.to_s].blank?
338
301
  nested_associations << resource_name
339
- resources[resource_name].to_hash(object.send(name), resources, nested_associations.dup)
302
+ resources[resource_name].to_hash(object.send(name), resources, model, nested_associations.dup)
340
303
  end
341
304
  hash
342
305
  end
@@ -345,10 +308,39 @@ class Traim
345
308
 
346
309
  class Model
347
310
 
348
- def initialize(model)
349
- @model = model
311
+ def initialize(model, request = nil)
312
+ @model = model
313
+ @request = request
314
+ @headers = {}
315
+ ok
316
+ end
317
+
318
+ attr_accessor :id
319
+ attr_accessor :model
320
+ attr_accessor :record
321
+ attr_accessor :params
322
+ attr_accessor :request
323
+ attr_accessor :status
324
+
325
+ def logger; Traim.logger end
326
+
327
+ # status code sytax suger
328
+ def ok; @status = 200 end
329
+ def created; @status = 201 end
330
+ def no_cotent; @status = 204 end
331
+
332
+ def instance_record(id)
333
+ @id = id
334
+ @record = show(@id)
350
335
  end
351
336
 
337
+ def headers(key = nil, value = nil)
338
+ return @headers if key.nil?
339
+ @headers[key] = value
340
+ end
341
+
342
+ def record; @record ||= show(id) end
343
+
352
344
  def create(params)
353
345
  resource = @model.new(params)
354
346
  resource.save
@@ -3,7 +3,7 @@ require_relative "../lib/traim"
3
3
 
4
4
  Traim.config do |app|
5
5
  app.logger = Logger.new(STDOUT)
6
- app.logger.level = Logger::DEBUG
6
+ app.logger.level = Logger::INFO
7
7
  end
8
8
 
9
9
  class User < ActiveRecord::Base
@@ -73,10 +73,9 @@ test "customize functionality" do |user|
73
73
  attribute :id
74
74
  attribute :name
75
75
 
76
- action :show do |params|
77
- user = model.find params["id"]
78
- user.name = "[admin] #{user.name}"
79
- user
76
+ action :show do
77
+ record.name = "[admin] #{record.name}"
78
+ record
80
79
  end
81
80
  end
82
81
  end
@@ -95,19 +94,20 @@ test "member create, read, update and destory functionality" do |user|
95
94
  attribute :name
96
95
 
97
96
  member :blurred do
98
- show do |params|
97
+ show do
99
98
  logger.info("show blurred")
99
+ logger.info("class #{self.class.name}")
100
100
  record.name[1..2] = "xx"
101
101
  record
102
102
  end
103
103
 
104
- update do |params|
105
- record.assign_attributes(params["payload"])
104
+ update do
105
+ record.assign_attributes(params)
106
106
  record.save
107
107
  record
108
108
  end
109
109
 
110
- destory do |params|
110
+ destory do
111
111
  record.delete
112
112
  end
113
113
  end
@@ -138,12 +138,12 @@ test "collection create, read, update and destory functionality" do |user|
138
138
  attribute :name
139
139
 
140
140
  collection :admin do
141
- show do |params|
141
+ show do
142
142
  model.all
143
143
  end
144
144
 
145
- create do |params|
146
- model.create(params["payload"])
145
+ create do
146
+ model.create(params)
147
147
  end
148
148
  end
149
149
  end
@@ -193,13 +193,13 @@ test "has many functionality" do |user|
193
193
  action :show
194
194
 
195
195
  collection :admin do
196
- show do |params|
196
+ show do
197
197
  model.all
198
198
  end
199
199
 
200
- create do |params|
200
+ create do
201
201
  # what to response?
202
- model.create(params["payload"])
202
+ model.create(params)
203
203
  end
204
204
  end
205
205
  end
@@ -322,19 +322,19 @@ test "helpers functionality" do |user|
322
322
  attribute :name
323
323
 
324
324
  member :blurred do
325
- show do |params|
325
+ show do
326
326
  auth('test')
327
327
  record.name[1..2] = "xx"
328
328
  record
329
329
  end
330
330
 
331
- update do |params|
332
- record.assign_attributes(params["payload"])
331
+ update do
332
+ record.assign_attributes(params)
333
333
  record.save
334
334
  record
335
335
  end
336
336
 
337
- destory do |params|
337
+ destory do
338
338
  record.delete
339
339
  end
340
340
  end
@@ -362,7 +362,7 @@ test "headers functionality" do |user|
362
362
  attribute :name
363
363
 
364
364
  member :headers do
365
- show do |params|
365
+ show do
366
366
  headers("test", "yeah")
367
367
  record
368
368
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "traim"
3
- s.version = "0.1.3"
3
+ s.version = "0.2.0"
4
4
  s.summary = %{Resource-oriented microframework for RESTful API}
5
5
  s.description = %Q{Resource-oriented microframework for RESTful API}
6
6
  s.authors = ["Travis Liu"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Liu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-02 00:00:00.000000000 Z
11
+ date: 2018-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack