jpie 0.3.1 → 0.4.1

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.
@@ -0,0 +1,146 @@
1
+ # Basic JPie Example
2
+
3
+ This example shows the minimal setup to get a JPie resource working with HTTP requests and responses.
4
+
5
+ ## Setup
6
+
7
+ ### 1. Model (`app/models/user.rb`)
8
+ ```ruby
9
+ class User < ActiveRecord::Base
10
+ validates :name, presence: true
11
+ validates :email, presence: true, uniqueness: true
12
+ end
13
+ ```
14
+
15
+ ### 2. Resource (`app/resources/user_resource.rb`)
16
+ ```ruby
17
+ class UserResource < JPie::Resource
18
+ attributes :name, :email
19
+ end
20
+ ```
21
+
22
+ ### 3. Controller (`app/controllers/users_controller.rb`)
23
+ ```ruby
24
+ class UsersController < ApplicationController
25
+ include JPie::Controller
26
+ end
27
+ ```
28
+
29
+ ### 4. Routes (`config/routes.rb`)
30
+ ```ruby
31
+ Rails.application.routes.draw do
32
+ resources :users
33
+ end
34
+ ```
35
+
36
+ ## HTTP Examples
37
+
38
+ ### Create User
39
+ ```http
40
+ POST /users
41
+ Content-Type: application/vnd.api+json
42
+
43
+ {
44
+ "data": {
45
+ "type": "users",
46
+ "attributes": {
47
+ "name": "John Doe",
48
+ "email": "john@example.com"
49
+ }
50
+ }
51
+ }
52
+
53
+ HTTP/1.1 201 Created
54
+ Content-Type: application/vnd.api+json
55
+
56
+ {
57
+ "data": {
58
+ "id": "1",
59
+ "type": "users",
60
+ "attributes": {
61
+ "name": "John Doe",
62
+ "email": "john@example.com"
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### Get All Users
69
+ ```http
70
+ GET /users
71
+ Accept: application/vnd.api+json
72
+
73
+ HTTP/1.1 200 OK
74
+ Content-Type: application/vnd.api+json
75
+
76
+ {
77
+ "data": [
78
+ {
79
+ "id": "1",
80
+ "type": "users",
81
+ "attributes": {
82
+ "name": "John Doe",
83
+ "email": "john@example.com"
84
+ }
85
+ }
86
+ ]
87
+ }
88
+ ```
89
+
90
+ ### Get Single User
91
+ ```http
92
+ GET /users/1
93
+ Accept: application/vnd.api+json
94
+
95
+ HTTP/1.1 200 OK
96
+ Content-Type: application/vnd.api+json
97
+
98
+ {
99
+ "data": {
100
+ "id": "1",
101
+ "type": "users",
102
+ "attributes": {
103
+ "name": "John Doe",
104
+ "email": "john@example.com"
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Update User
111
+ ```http
112
+ PATCH /users/1
113
+ Content-Type: application/vnd.api+json
114
+
115
+ {
116
+ "data": {
117
+ "id": "1",
118
+ "type": "users",
119
+ "attributes": {
120
+ "name": "Jane Doe"
121
+ }
122
+ }
123
+ }
124
+
125
+ HTTP/1.1 200 OK
126
+ Content-Type: application/vnd.api+json
127
+
128
+ {
129
+ "data": {
130
+ "id": "1",
131
+ "type": "users",
132
+ "attributes": {
133
+ "name": "Jane Doe",
134
+ "email": "john@example.com"
135
+ }
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### Delete User
141
+ ```http
142
+ DELETE /users/1
143
+ Accept: application/vnd.api+json
144
+
145
+ HTTP/1.1 204 No Content
146
+ ```
@@ -0,0 +1,491 @@
1
+ # Including Related Resources Example
2
+
3
+ This example demonstrates how to include related resources in JPie responses using the `include` parameter, showcasing various relationship types and nested includes.
4
+
5
+ ## Setup
6
+
7
+ ### 1. Models (`app/models/`)
8
+
9
+ ```ruby
10
+ # app/models/user.rb
11
+ class User < ActiveRecord::Base
12
+ validates :name, presence: true
13
+ validates :email, presence: true, uniqueness: true
14
+
15
+ has_many :posts, dependent: :destroy
16
+ has_many :comments, dependent: :destroy
17
+ has_one :profile, dependent: :destroy
18
+ end
19
+
20
+ # app/models/post.rb
21
+ class Post < ActiveRecord::Base
22
+ validates :title, presence: true
23
+ validates :content, presence: true
24
+
25
+ belongs_to :user
26
+ has_many :comments, dependent: :destroy
27
+ has_many :tags, through: :taggings
28
+ end
29
+
30
+ # app/models/comment.rb
31
+ class Comment < ActiveRecord::Base
32
+ validates :content, presence: true
33
+
34
+ belongs_to :user
35
+ belongs_to :post
36
+ has_many :tags, through: :taggings
37
+ end
38
+
39
+ # app/models/profile.rb
40
+ class Profile < ActiveRecord::Base
41
+ validates :bio, presence: true
42
+
43
+ belongs_to :user
44
+ end
45
+
46
+ # app/models/tag.rb
47
+ class Tag < ActiveRecord::Base
48
+ validates :name, presence: true, uniqueness: true
49
+
50
+ has_many :taggings, dependent: :destroy
51
+ has_many :posts, through: :taggings, source: :taggable, source_type: 'Post'
52
+ has_many :comments, through: :taggings, source: :taggable, source_type: 'Comment'
53
+ end
54
+ ```
55
+
56
+ ### 2. Resources (`app/resources/`)
57
+
58
+ ```ruby
59
+ # app/resources/user_resource.rb
60
+ class UserResource < JPie::Resource
61
+ attributes :name, :email
62
+ meta_attributes :created_at, :updated_at
63
+
64
+ has_many :posts
65
+ has_many :comments
66
+ has_one :profile
67
+ end
68
+
69
+ # app/resources/post_resource.rb
70
+ class PostResource < JPie::Resource
71
+ attributes :title, :content
72
+ meta_attributes :created_at, :updated_at
73
+
74
+ has_one :user
75
+ has_many :comments
76
+ has_many :tags
77
+ end
78
+
79
+ # app/resources/comment_resource.rb
80
+ class CommentResource < JPie::Resource
81
+ attributes :content
82
+ meta_attributes :created_at, :updated_at
83
+
84
+ has_one :user
85
+ has_one :post
86
+ has_many :tags
87
+ end
88
+
89
+ # app/resources/profile_resource.rb
90
+ class ProfileResource < JPie::Resource
91
+ attributes :bio, :website
92
+ meta_attributes :created_at, :updated_at
93
+
94
+ has_one :user
95
+ end
96
+
97
+ # app/resources/tag_resource.rb
98
+ class TagResource < JPie::Resource
99
+ attributes :name
100
+ meta_attributes :created_at, :updated_at
101
+
102
+ has_many :posts
103
+ has_many :comments
104
+ end
105
+ ```
106
+
107
+ ### 3. Controller (`app/controllers/posts_controller.rb`)
108
+
109
+ ```ruby
110
+ class PostsController < ApplicationController
111
+ include JPie::Controller
112
+ end
113
+ ```
114
+
115
+ ## HTTP Examples
116
+
117
+ ### Create Post with Included User
118
+ ```http
119
+ POST /posts?include=user
120
+ Content-Type: application/vnd.api+json
121
+
122
+ {
123
+ "data": {
124
+ "type": "posts",
125
+ "attributes": {
126
+ "title": "Getting Started with JPie",
127
+ "content": "This post explains how to use JPie...",
128
+ "user_id": 1
129
+ }
130
+ }
131
+ }
132
+
133
+ HTTP/1.1 201 Created
134
+ Content-Type: application/vnd.api+json
135
+
136
+ {
137
+ "data": {
138
+ "id": "1",
139
+ "type": "posts",
140
+ "attributes": {
141
+ "title": "Getting Started with JPie",
142
+ "content": "This post explains how to use JPie..."
143
+ },
144
+ "meta": {
145
+ "created_at": "2024-01-15T10:30:00Z",
146
+ "updated_at": "2024-01-15T10:30:00Z"
147
+ }
148
+ },
149
+ "included": [
150
+ {
151
+ "id": "1",
152
+ "type": "users",
153
+ "attributes": {
154
+ "name": "John Doe",
155
+ "email": "john@example.com"
156
+ },
157
+ "meta": {
158
+ "created_at": "2024-01-10T09:00:00Z",
159
+ "updated_at": "2024-01-10T09:00:00Z"
160
+ }
161
+ }
162
+ ]
163
+ }
164
+ ```
165
+
166
+ ### Update Post with Included User and Comments
167
+ ```http
168
+ PATCH /posts/1?include=user,comments
169
+ Content-Type: application/vnd.api+json
170
+
171
+ {
172
+ "data": {
173
+ "id": "1",
174
+ "type": "posts",
175
+ "attributes": {
176
+ "title": "Advanced JPie Techniques"
177
+ }
178
+ }
179
+ }
180
+
181
+ HTTP/1.1 200 OK
182
+ Content-Type: application/vnd.api+json
183
+
184
+ {
185
+ "data": {
186
+ "id": "1",
187
+ "type": "posts",
188
+ "attributes": {
189
+ "title": "Advanced JPie Techniques",
190
+ "content": "This post explains how to use JPie..."
191
+ },
192
+ "meta": {
193
+ "created_at": "2024-01-15T10:30:00Z",
194
+ "updated_at": "2024-01-15T11:00:00Z"
195
+ }
196
+ },
197
+ "included": [
198
+ {
199
+ "id": "1",
200
+ "type": "users",
201
+ "attributes": {
202
+ "name": "John Doe",
203
+ "email": "john@example.com"
204
+ },
205
+ "meta": {
206
+ "created_at": "2024-01-10T09:00:00Z",
207
+ "updated_at": "2024-01-10T09:00:00Z"
208
+ }
209
+ },
210
+ {
211
+ "id": "1",
212
+ "type": "comments",
213
+ "attributes": {
214
+ "content": "Great post! Very helpful."
215
+ },
216
+ "meta": {
217
+ "created_at": "2024-01-15T11:00:00Z",
218
+ "updated_at": "2024-01-15T11:00:00Z"
219
+ }
220
+ }
221
+ ]
222
+ }
223
+ ```
224
+
225
+ ### Single Include - Post with User
226
+ ```http
227
+ GET /posts/1?include=user
228
+ Accept: application/vnd.api+json
229
+
230
+ HTTP/1.1 200 OK
231
+ Content-Type: application/vnd.api+json
232
+
233
+ {
234
+ "data": {
235
+ "id": "1",
236
+ "type": "posts",
237
+ "attributes": {
238
+ "title": "Getting Started with JPie",
239
+ "content": "This post explains how to use JPie..."
240
+ },
241
+ "meta": {
242
+ "created_at": "2024-01-15T10:30:00Z",
243
+ "updated_at": "2024-01-15T10:30:00Z"
244
+ }
245
+ },
246
+ "included": [
247
+ {
248
+ "id": "1",
249
+ "type": "users",
250
+ "attributes": {
251
+ "name": "John Doe",
252
+ "email": "john@example.com"
253
+ },
254
+ "meta": {
255
+ "created_at": "2024-01-10T09:00:00Z",
256
+ "updated_at": "2024-01-10T09:00:00Z"
257
+ }
258
+ }
259
+ ]
260
+ }
261
+ ```
262
+
263
+ ### Multiple Includes - Post with User and Comments
264
+ ```http
265
+ GET /posts/1?include=user,comments
266
+ Accept: application/vnd.api+json
267
+
268
+ HTTP/1.1 200 OK
269
+ Content-Type: application/vnd.api+json
270
+
271
+ {
272
+ "data": {
273
+ "id": "1",
274
+ "type": "posts",
275
+ "attributes": {
276
+ "title": "Getting Started with JPie",
277
+ "content": "This post explains how to use JPie..."
278
+ },
279
+ "meta": {
280
+ "created_at": "2024-01-15T10:30:00Z",
281
+ "updated_at": "2024-01-15T10:30:00Z"
282
+ }
283
+ },
284
+ "included": [
285
+ {
286
+ "id": "1",
287
+ "type": "users",
288
+ "attributes": {
289
+ "name": "John Doe",
290
+ "email": "john@example.com"
291
+ },
292
+ "meta": {
293
+ "created_at": "2024-01-10T09:00:00Z",
294
+ "updated_at": "2024-01-10T09:00:00Z"
295
+ }
296
+ },
297
+ {
298
+ "id": "1",
299
+ "type": "comments",
300
+ "attributes": {
301
+ "content": "Great post! Very helpful."
302
+ },
303
+ "meta": {
304
+ "created_at": "2024-01-15T11:00:00Z",
305
+ "updated_at": "2024-01-15T11:00:00Z"
306
+ }
307
+ },
308
+ {
309
+ "id": "2",
310
+ "type": "comments",
311
+ "attributes": {
312
+ "content": "Thanks for sharing this."
313
+ },
314
+ "meta": {
315
+ "created_at": "2024-01-15T12:00:00Z",
316
+ "updated_at": "2024-01-15T12:00:00Z"
317
+ }
318
+ }
319
+ ]
320
+ }
321
+ ```
322
+
323
+ ### Nested Includes - Post with User and User's Profile
324
+ ```http
325
+ GET /posts/1?include=user.profile
326
+ Accept: application/vnd.api+json
327
+
328
+ HTTP/1.1 200 OK
329
+ Content-Type: application/vnd.api+json
330
+
331
+ {
332
+ "data": {
333
+ "id": "1",
334
+ "type": "posts",
335
+ "attributes": {
336
+ "title": "Getting Started with JPie",
337
+ "content": "This post explains how to use JPie..."
338
+ },
339
+ "meta": {
340
+ "created_at": "2024-01-15T10:30:00Z",
341
+ "updated_at": "2024-01-15T10:30:00Z"
342
+ }
343
+ },
344
+ "included": [
345
+ {
346
+ "id": "1",
347
+ "type": "users",
348
+ "attributes": {
349
+ "name": "John Doe",
350
+ "email": "john@example.com"
351
+ },
352
+ "meta": {
353
+ "created_at": "2024-01-10T09:00:00Z",
354
+ "updated_at": "2024-01-10T09:00:00Z"
355
+ }
356
+ },
357
+ {
358
+ "id": "1",
359
+ "type": "profiles",
360
+ "attributes": {
361
+ "bio": "Software developer passionate about clean APIs",
362
+ "website": "https://johndoe.dev"
363
+ },
364
+ "meta": {
365
+ "created_at": "2024-01-10T09:30:00Z",
366
+ "updated_at": "2024-01-12T14:00:00Z"
367
+ }
368
+ }
369
+ ]
370
+ }
371
+ ```
372
+
373
+ ### Complex Nested Includes - Post with Comments and Comment Users
374
+ ```http
375
+ GET /posts/1?include=comments.user
376
+ Accept: application/vnd.api+json
377
+
378
+ HTTP/1.1 200 OK
379
+ Content-Type: application/vnd.api+json
380
+
381
+ {
382
+ "data": {
383
+ "id": "1",
384
+ "type": "posts",
385
+ "attributes": {
386
+ "title": "Getting Started with JPie",
387
+ "content": "This post explains how to use JPie..."
388
+ },
389
+ "meta": {
390
+ "created_at": "2024-01-15T10:30:00Z",
391
+ "updated_at": "2024-01-15T10:30:00Z"
392
+ }
393
+ },
394
+ "included": [
395
+ {
396
+ "id": "1",
397
+ "type": "comments",
398
+ "attributes": {
399
+ "content": "Great post! Very helpful."
400
+ },
401
+ "meta": {
402
+ "created_at": "2024-01-15T11:00:00Z",
403
+ "updated_at": "2024-01-15T11:00:00Z"
404
+ }
405
+ },
406
+ {
407
+ "id": "2",
408
+ "type": "comments",
409
+ "attributes": {
410
+ "content": "Thanks for sharing this."
411
+ },
412
+ "meta": {
413
+ "created_at": "2024-01-15T12:00:00Z",
414
+ "updated_at": "2024-01-15T12:00:00Z"
415
+ }
416
+ },
417
+ {
418
+ "id": "1",
419
+ "type": "users",
420
+ "attributes": {
421
+ "name": "John Doe",
422
+ "email": "john@example.com"
423
+ },
424
+ "meta": {
425
+ "created_at": "2024-01-10T09:00:00Z",
426
+ "updated_at": "2024-01-10T09:00:00Z"
427
+ }
428
+ },
429
+ {
430
+ "id": "2",
431
+ "type": "users",
432
+ "attributes": {
433
+ "name": "Jane Smith",
434
+ "email": "jane@example.com"
435
+ },
436
+ "meta": {
437
+ "created_at": "2024-01-12T08:00:00Z",
438
+ "updated_at": "2024-01-12T08:00:00Z"
439
+ }
440
+ }
441
+ ]
442
+ }
443
+ ```
444
+
445
+ ### Through Association - Post with Tags
446
+ ```http
447
+ GET /posts/1?include=tags
448
+ Accept: application/vnd.api+json
449
+
450
+ HTTP/1.1 200 OK
451
+ Content-Type: application/vnd.api+json
452
+
453
+ {
454
+ "data": {
455
+ "id": "1",
456
+ "type": "posts",
457
+ "attributes": {
458
+ "title": "Getting Started with JPie",
459
+ "content": "This post explains how to use JPie..."
460
+ },
461
+ "meta": {
462
+ "created_at": "2024-01-15T10:30:00Z",
463
+ "updated_at": "2024-01-15T10:30:00Z"
464
+ }
465
+ },
466
+ "included": [
467
+ {
468
+ "id": "1",
469
+ "type": "tags",
470
+ "attributes": {
471
+ "name": "ruby"
472
+ },
473
+ "meta": {
474
+ "created_at": "2024-01-01T00:00:00Z",
475
+ "updated_at": "2024-01-01T00:00:00Z"
476
+ }
477
+ },
478
+ {
479
+ "id": "2",
480
+ "type": "tags",
481
+ "attributes": {
482
+ "name": "api"
483
+ },
484
+ "meta": {
485
+ "created_at": "2024-01-01T00:00:00Z",
486
+ "updated_at": "2024-01-01T00:00:00Z"
487
+ }
488
+ }
489
+ ]
490
+ }
491
+ ```