traim 0.1.3 → 0.2.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 (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