nested 0.0.26 → 0.0.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +202 -3
- data/lib/nested/serializer.rb +2 -0
- data/nested.gemspec +1 -1
- data/test/serializer_test.rb +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab13bf160d76af854150cd009b1f59116a0c58bc
|
4
|
+
data.tar.gz: df0fe620f543a2f267634f88d86fde251ce9d2e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5eebaafea98746566bfd1b60dda1f5cfeda99920d4d6e804d132b2e2ac236e233ce370168f7b1c08f1f85806b69b9e34f7717c8e4e2de732a5a09f2653f3b7ca
|
7
|
+
data.tar.gz: f79bea6564bd4c80fa2ef5bf7ae8df1c2a1617f8a5d11c48123ab6a2fdb31817b7c5e0fa4a30c2799a1ed403938fbd74ee48941049fb2587bb5d90ed02784c7e
|
data/README.md
CHANGED
@@ -1,4 +1,203 @@
|
|
1
|
-
|
2
|
-
======
|
1
|
+
# Nested
|
3
2
|
|
4
|
-
a
|
3
|
+
Nested is a DSL to create a restful API in a declarative way. It is implemented in ruby. The author has some strong opinions about REST/API.
|
4
|
+
|
5
|
+
## Quickstart
|
6
|
+
|
7
|
+
Nested provides you a bunch of keywords to declare the resources of your API. Most important are "singleton", "many" and "one".
|
8
|
+
|
9
|
+
```
|
10
|
+
class MyApi < Nested::App
|
11
|
+
singleton :user
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
You just declared your first resource! But it does not do much right, so lets add a HTTP verb to make it accessible.
|
16
|
+
|
17
|
+
```
|
18
|
+
class MyApi < Nested::App
|
19
|
+
singleton :user do
|
20
|
+
get
|
21
|
+
end
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
Now our resource is reachable by issuing a GET request to "/user". It still does not return any useful data. A resources is always backed by a model. Mostly you will use an array, hash or orm-instances (e.g. activerecord) as underlying model. The easiest way is to provide a block to your resource.
|
26
|
+
|
27
|
+
```
|
28
|
+
class MyApi < Nested::App
|
29
|
+
singleton :user, ->{ {name: "joe"} } do
|
30
|
+
get
|
31
|
+
end
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
The model block will be invoked each time the resource is requested. We still do not get back the underlying model from our resource. In nested you have to explicitly whitelist which fields your want to expose for a resource.
|
36
|
+
|
37
|
+
```
|
38
|
+
class MyApi < Nested::App
|
39
|
+
singleton :user, ->{ {id: 99, name: "joe"} } do
|
40
|
+
serialize :id, :name
|
41
|
+
get
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Congrats! You just created your first nested API. Checkout the other sections to get more information about different resource types, verbs, serialization and conditionals.
|
47
|
+
|
48
|
+
## Nested:App
|
49
|
+
|
50
|
+
In nested you implement your API as a normal ruby class which inherit from Nested::App
|
51
|
+
|
52
|
+
```
|
53
|
+
class MyApi < Nested::App
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## Resources
|
58
|
+
|
59
|
+
### Singleton
|
60
|
+
|
61
|
+
A unique value.
|
62
|
+
|
63
|
+
```
|
64
|
+
class MyApi < Nested::App
|
65
|
+
# the current user
|
66
|
+
singleton :user do
|
67
|
+
serialize :id, :email, :username
|
68
|
+
|
69
|
+
# GET /user
|
70
|
+
get
|
71
|
+
end
|
72
|
+
|
73
|
+
# session which is used to login/logout
|
74
|
+
singleton :session do
|
75
|
+
# perform login, POST /session
|
76
|
+
post
|
77
|
+
|
78
|
+
# perform logout, DELETE /session
|
79
|
+
delete
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
### Many
|
85
|
+
|
86
|
+
A list of values.
|
87
|
+
|
88
|
+
```
|
89
|
+
class MyApi < Nested::App
|
90
|
+
many :tasks do
|
91
|
+
serialize :id, :title, :description
|
92
|
+
|
93
|
+
# GET /tasks
|
94
|
+
get
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
### One
|
100
|
+
|
101
|
+
A specific value of many resource.
|
102
|
+
|
103
|
+
```
|
104
|
+
class MyApi < Nested::App
|
105
|
+
many :tasks do
|
106
|
+
serialize :id, :title, :description
|
107
|
+
|
108
|
+
# GET /tasks
|
109
|
+
get
|
110
|
+
|
111
|
+
one do
|
112
|
+
# GET /tasks/:id
|
113
|
+
get
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
One can only be used within a enclosing Many. One inherits its name and serialization information from the Many.
|
120
|
+
|
121
|
+
## Http Verbs
|
122
|
+
|
123
|
+
Nested supports all commonly used http verbs used in a resftul API. Call the verb as method inside the resource block to make the resource respond to that http verb.
|
124
|
+
|
125
|
+
```
|
126
|
+
class MyApi < Nested::App
|
127
|
+
singleton :user do
|
128
|
+
# respond to GET /user
|
129
|
+
get
|
130
|
+
|
131
|
+
# respond to POST /user
|
132
|
+
post
|
133
|
+
|
134
|
+
# respond to DELETE /user
|
135
|
+
delete
|
136
|
+
|
137
|
+
# respond to PUT /user
|
138
|
+
put
|
139
|
+
|
140
|
+
# respond to PATCH /user
|
141
|
+
patch
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
You can pass a block to each http verb to impement the concret behavior.
|
146
|
+
|
147
|
+
```
|
148
|
+
class MyApi < Nested::App
|
149
|
+
singleton :user, ->{ {name: "joe" } } do
|
150
|
+
get do
|
151
|
+
puts "i am a GET request"
|
152
|
+
end
|
153
|
+
|
154
|
+
delete do
|
155
|
+
puts "and i am a DELETE one"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
The http verb block can access the model of the resource as an instance variable.
|
162
|
+
|
163
|
+
```
|
164
|
+
class MyApi < Nested::App
|
165
|
+
singleton :user, ->{ {name: "joe" } } do
|
166
|
+
get do
|
167
|
+
puts "my name is #{@user.name}"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
The model is available in all http verb block. Except inpost. The post block has to return a new model.
|
174
|
+
|
175
|
+
```
|
176
|
+
class MyApi < Nested::App
|
177
|
+
singleton :user do
|
178
|
+
post do
|
179
|
+
{name: "joe"}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
```
|
184
|
+
|
185
|
+
Nested gives you access to http parameters through the params method as known from other frameworks and addition to this a useful shorthand.
|
186
|
+
|
187
|
+
```
|
188
|
+
class MyApi < Nested::App
|
189
|
+
singleton :user, ->{ {name: "joe", age: 33 } } do
|
190
|
+
put do
|
191
|
+
@user.name = params[:new_name]
|
192
|
+
@user.age = params[:age]
|
193
|
+
end
|
194
|
+
|
195
|
+
# same as
|
196
|
+
|
197
|
+
put do |new_name, age|
|
198
|
+
@user.name = new_name
|
199
|
+
@user.age = age
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
```
|
data/lib/nested/serializer.rb
CHANGED
@@ -25,6 +25,8 @@ module Nested
|
|
25
25
|
def serialize
|
26
26
|
this = self
|
27
27
|
->(obj) do
|
28
|
+
obj = ::HashWithIndifferentAccess.new(obj) if obj.is_a?(Hash)
|
29
|
+
|
28
30
|
excludes = this.excludes.select{|e| instance_exec(&e.condition)}
|
29
31
|
|
30
32
|
this.includes.reject{|e| excludes.detect{|e2| e2.name == e.name}}.inject({}) do |memo, field|
|
data/nested.gemspec
CHANGED
data/test/serializer_test.rb
CHANGED
@@ -28,4 +28,28 @@ class SerializerTest < Test::Unit::TestCase
|
|
28
28
|
assert_equal :name, ser.excludes[0].name
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_serialize
|
32
|
+
ser = Nested::Serializer.new()
|
33
|
+
ser + :id
|
34
|
+
|
35
|
+
obj = {id: 2, name: "joe"}
|
36
|
+
|
37
|
+
assert_equal({id: 2}, obj.instance_eval(&ser.serialize))
|
38
|
+
|
39
|
+
ser + :name
|
40
|
+
assert_equal({id: 2, name: "joe"}, obj.instance_eval(&ser.serialize))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_serialize_with_symbolize_keys
|
44
|
+
ser = Nested::Serializer.new()
|
45
|
+
ser + :id
|
46
|
+
|
47
|
+
obj = {"id" => 2, "name" => "joe"}
|
48
|
+
|
49
|
+
assert_equal({id: 2}, obj.instance_eval(&ser.serialize))
|
50
|
+
|
51
|
+
ser + :name
|
52
|
+
assert_equal({id: 2, name: "joe"}, obj.instance_eval(&ser.serialize))
|
53
|
+
end
|
54
|
+
|
31
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nested
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Zimmek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|