collection-json 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/README.md +134 -0
- data/Rakefile +1 -0
- data/collection-json.gemspec +18 -0
- data/lib/collection-json.rb +26 -0
- data/lib/collection-json/builder.rb +105 -0
- data/lib/collection-json/response.rb +37 -0
- data/lib/collection-json/version.rb +3 -0
- metadata +54 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# CollectionJSON
|
2
|
+
|
3
|
+
A lightweight gem to easily build response objects with a MIME type of
|
4
|
+
'application/vnd.collection+json'.
|
5
|
+
|
6
|
+
Read http://amundsen.com/media-types/collection/ for more information about this
|
7
|
+
media type.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
Use ```CollectionJSON.generate_for``` to build a response object which you can
|
12
|
+
call ```to_json``` on.
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
response = CollectionJSON.generate_for('/friends/') do |builder|
|
16
|
+
builder.add_link '/friends/rss', 'feed'
|
17
|
+
user.friends.each do |friend|
|
18
|
+
builder.add_item("/friends/#{friend.id}") do |item|
|
19
|
+
item.add_data "full-name", friend.full_name
|
20
|
+
item.add_data "email", friend.email
|
21
|
+
item.add_link "/blogs/#{friend.id}", "blog", "", "Blog"
|
22
|
+
item.add_link "/blogs/#{friend.id}", "avatar", "", "Avatar", "image"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
builder.add_query("/friends/search", "search", "Search") do |query|
|
26
|
+
query.add_data "search"
|
27
|
+
end
|
28
|
+
builder.set_template do |template|
|
29
|
+
template.add_data "full-name", "", "Full Name"
|
30
|
+
template.add_data "email", "", "Email"
|
31
|
+
template.add_data "blog", "", "Blog"
|
32
|
+
template.add_data "avatar", "", "Avatar"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
response.to_json
|
37
|
+
```
|
38
|
+
|
39
|
+
Sample output:
|
40
|
+
|
41
|
+
```javascript
|
42
|
+
{ "collection" :
|
43
|
+
{
|
44
|
+
"version" : "1.0",
|
45
|
+
"href" : "http://example.org/friends/",
|
46
|
+
|
47
|
+
"links" : [
|
48
|
+
{"rel" : "feed", "href" : "http://example.org/friends/rss"}
|
49
|
+
],
|
50
|
+
|
51
|
+
"items" : [
|
52
|
+
{
|
53
|
+
"href" : "http://example.org/friends/jdoe",
|
54
|
+
"data" : [
|
55
|
+
{"name" : "full-name", "value" : "J. Doe", "prompt" : "Full Name"},
|
56
|
+
{"name" : "email", "value" : "jdoe@example.org", "prompt" : "Email"}
|
57
|
+
],
|
58
|
+
"links" : [
|
59
|
+
{"rel" : "blog", "href" : "http://example.org/blogs/jdoe", "prompt" : "Blog"},
|
60
|
+
{
|
61
|
+
"rel" : "avatar", "href" : "http://example.org/images/jdoe",
|
62
|
+
"prompt" : "Avatar", "render" : "image"
|
63
|
+
}
|
64
|
+
]
|
65
|
+
},
|
66
|
+
|
67
|
+
{
|
68
|
+
"href" : "http://example.org/friends/msmith",
|
69
|
+
"data" : [
|
70
|
+
{"name" : "full-name", "value" : "M. Smith", "prompt" : "Full Name"},
|
71
|
+
{"name" : "email", "value" : "msmith@example.org", "prompt" : "Email"}
|
72
|
+
],
|
73
|
+
"links" : [
|
74
|
+
{"rel" : "blog", "href" : "http://example.org/blogs/msmith", "prompt" : "Blog"},
|
75
|
+
{
|
76
|
+
"rel" : "avatar", "href" : "http://example.org/images/msmith",
|
77
|
+
"prompt" : "Avatar", "render" : "image"
|
78
|
+
}
|
79
|
+
]
|
80
|
+
},
|
81
|
+
|
82
|
+
{
|
83
|
+
"href" : "http://example.org/friends/rwilliams",
|
84
|
+
"data" : [
|
85
|
+
{"name" : "full-name", "value" : "R. Williams", "prompt" : "Full Name"},
|
86
|
+
{"name" : "email", "value" : "rwilliams@example.org", "prompt" : "Email"}
|
87
|
+
],
|
88
|
+
"links" : [
|
89
|
+
{"rel" : "blog", "href" : "http://example.org/blogs/rwilliams", "prompt" : "Blog"},
|
90
|
+
{
|
91
|
+
"rel" : "avatar", "href" : "http://example.org/images/rwilliams",
|
92
|
+
"prompt" : "Avatar", "render" : "image"
|
93
|
+
}
|
94
|
+
]
|
95
|
+
}
|
96
|
+
],
|
97
|
+
|
98
|
+
"queries" : [
|
99
|
+
{"rel" : "search", "href" : "http://example.org/friends/search", "prompt" : "Search",
|
100
|
+
"data" : [
|
101
|
+
{"name" : "search"}
|
102
|
+
]
|
103
|
+
}
|
104
|
+
],
|
105
|
+
|
106
|
+
"template" : {
|
107
|
+
"data" : [
|
108
|
+
{"name" : "full-name", "prompt" : "Full Name"},
|
109
|
+
{"name" : "email", "prompt" : "Email"},
|
110
|
+
{"name" : "blog", "prompt" : "Blog"},
|
111
|
+
{"name" : "avatar", "prompt" : "Avatar"}
|
112
|
+
|
113
|
+
]
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
```
|
118
|
+
|
119
|
+
Set the ```COLLECTION_JSON_HOST``` environment variable to automatically add
|
120
|
+
this to the href's. Eg. ```COLLECTION_JSON_HOST=http://example.org```
|
121
|
+
|
122
|
+
## Installation
|
123
|
+
|
124
|
+
Add this line to your application's Gemfile:
|
125
|
+
|
126
|
+
gem 'collection-json'
|
127
|
+
|
128
|
+
And then execute:
|
129
|
+
|
130
|
+
$ bundle
|
131
|
+
|
132
|
+
Or install it yourself as:
|
133
|
+
|
134
|
+
$ gem install collection-json
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "collection-json/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "collection-json"
|
7
|
+
s.version = CollectionJSON::VERSION
|
8
|
+
s.authors = ["Sebastian Edwards"]
|
9
|
+
s.email = ["sebastian@uprise.co.nz"]
|
10
|
+
s.homepage = "https://github.com/sebastianedwards/collection-json"
|
11
|
+
s.summary = %q{Builds Collection+JSON responses.}
|
12
|
+
s.description = %q{Lightweight gem for building Collection+JSON responses.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "collection-json"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "collection-json/version"
|
2
|
+
require "collection-json/response"
|
3
|
+
require "collection-json/builder"
|
4
|
+
|
5
|
+
COLLECTION_JSON_VERSION = "1.0"
|
6
|
+
COLLECTION_JSON_HOST = ENV['COLLECTION_JSON_HOST']
|
7
|
+
|
8
|
+
module CollectionJSON
|
9
|
+
def self.generate_for(href, &block)
|
10
|
+
response = Response.new(href)
|
11
|
+
if block_given?
|
12
|
+
builder = Builder.new(response)
|
13
|
+
yield(builder)
|
14
|
+
end
|
15
|
+
|
16
|
+
response
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.add_host(href)
|
20
|
+
if COLLECTION_JSON_HOST && !href[/^http/]
|
21
|
+
COLLECTION_JSON_HOST + href
|
22
|
+
else
|
23
|
+
href
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module CollectionJSON
|
2
|
+
class Builder
|
3
|
+
attr_reader :response
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@response = response
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_error(opts = {})
|
10
|
+
response.error = opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_code(code)
|
14
|
+
response.code = code
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_link(href, rel, opts = {})
|
18
|
+
href = CollectionJSON.add_host(href)
|
19
|
+
response.links << opts.merge({rel: rel, href: href})
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_item(href, data = [], links = [], &block)
|
23
|
+
href = CollectionJSON.add_host(href)
|
24
|
+
response.items << {href: href}.tap do |item|
|
25
|
+
item_builder = ItemBuilder.new(data, links)
|
26
|
+
yield(item_builder) if block_given?
|
27
|
+
item.merge!({data: item_builder.data}) if item_builder.data.length > 0
|
28
|
+
item.merge!({links: item_builder.links}) if item_builder.links.length > 0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_query(href, rel, prompt = '', data = [], &block)
|
33
|
+
href = CollectionJSON.add_host(href)
|
34
|
+
response.queries << {href: href, rel: rel}.tap do |query|
|
35
|
+
query_builder = QueryBuilder.new(data)
|
36
|
+
yield(query_builder) if block_given?
|
37
|
+
query.merge!({prompt: prompt}) if prompt != ''
|
38
|
+
query.merge!({data: query_builder.data}) if query_builder.data.length > 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_template(data = [], &block)
|
43
|
+
response.template = Hash.new.tap do |template|
|
44
|
+
template_builder = TemplateBuilder.new(data)
|
45
|
+
yield(template_builder) if block_given?
|
46
|
+
template.merge!({data: template_builder.data}) if template_builder.data.length > 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class ItemBuilder
|
52
|
+
attr_reader :data, :links
|
53
|
+
|
54
|
+
def initialize(data, links)
|
55
|
+
@data = data
|
56
|
+
@links = links
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_data(name, value = '', prompt = '')
|
60
|
+
data << {name: name}.tap do |data|
|
61
|
+
data.merge!({value: value}) if value != ''
|
62
|
+
data.merge!({prompt: prompt}) if prompt != ''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_link(href, rel, name = '', prompt = '', render = '')
|
67
|
+
href = CollectionJSON.add_host(href)
|
68
|
+
links << {href: href, rel: rel}.tap do |link|
|
69
|
+
link.merge!({name: name}) if name != ''
|
70
|
+
link.merge!({prompt: prompt}) if prompt != ''
|
71
|
+
link.merge!({render: render}) if render != ''
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class QueryBuilder
|
77
|
+
attr_reader :data
|
78
|
+
|
79
|
+
def initialize(data)
|
80
|
+
@data = data
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_data(name, value = '', prompt = '')
|
84
|
+
data << {name: name}.tap do |data|
|
85
|
+
data.merge!({value: value}) if value != ''
|
86
|
+
data.merge!({prompt: prompt}) if prompt != ''
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class TemplateBuilder
|
92
|
+
attr_reader :data
|
93
|
+
|
94
|
+
def initialize(data)
|
95
|
+
@data = data
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_data(name, value = '', prompt = '')
|
99
|
+
data << {name: name}.tap do |data|
|
100
|
+
data.merge!({value: value}) if value != ''
|
101
|
+
data.merge!({prompt: prompt}) if prompt != ''
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module CollectionJSON
|
4
|
+
class Response
|
5
|
+
attr_reader :href, :links, :items, :queries, :template, :version, :error
|
6
|
+
attr_writer :links, :items, :queries, :template, :version, :error
|
7
|
+
|
8
|
+
def initialize(href)
|
9
|
+
@href = CollectionJSON.add_host(href)
|
10
|
+
@version = COLLECTION_JSON_VERSION
|
11
|
+
@items = []
|
12
|
+
@links = []
|
13
|
+
@queries = []
|
14
|
+
@error = nil
|
15
|
+
@template = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def body
|
19
|
+
{href: href, version: version}.tap do |body|
|
20
|
+
%w{items links queries}.each do |child_name|
|
21
|
+
child = send(child_name)
|
22
|
+
body.merge!({child_name => child}) if child.length > 0
|
23
|
+
end
|
24
|
+
body.merge!({error: error}) if error
|
25
|
+
body.merge!({template: template}) if template
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def collection
|
30
|
+
{collection: body}
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_json(*args)
|
34
|
+
collection.to_json(args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: collection-json
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sebastian Edwards
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-15 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Lightweight gem for building Collection+JSON responses.
|
15
|
+
email:
|
16
|
+
- sebastian@uprise.co.nz
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- collection-json.gemspec
|
26
|
+
- lib/collection-json.rb
|
27
|
+
- lib/collection-json/builder.rb
|
28
|
+
- lib/collection-json/response.rb
|
29
|
+
- lib/collection-json/version.rb
|
30
|
+
homepage: https://github.com/sebastianedwards/collection-json
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project: collection-json
|
50
|
+
rubygems_version: 1.8.15
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: Builds Collection+JSON responses.
|
54
|
+
test_files: []
|