collection-json 0.0.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.
- 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: []
|