jbuilder-json_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ff4461806b35c5a3d74588a69c25b2114cb229f
4
+ data.tar.gz: 14b6437c8ca3707ee94b7ecea417655976fb06d8
5
+ SHA512:
6
+ metadata.gz: 243d498cce513d4794dfa8babe42ee888f102b5dd328679bf923873597d5c4232425bcb67d329ed5a69ef3808e244066466b4133412b27709ee847ba21d23fc0
7
+ data.tar.gz: 297d98968a8d93e6628f309e5b21ad9954216327dca0d4962405233c540496f60a588d60a7cca8ba1ce226ecca74d1a356012fe8f42781d54c50e9d14e78b733
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Jbuilder::JsonApi | [![Build Status](https://travis-ci.org/vladfaust/jbuilder-json_api.svg?branch=master)](https://travis-ci.org/vladfaust/jbuilder-json_api) [![Code Climate](https://codeclimate.com/github/vladfaust/jbuilder-json_api/badges/gpa.svg)](https://codeclimate.com/github/vladfaust/jbuilder-json_api) [![Test Coverage](https://codeclimate.com/github/vladfaust/jbuilder-json_api/badges/coverage.svg)](https://codeclimate.com/github/vladfaust/jbuilder-json_api/coverage)
2
+
3
+ Adds a `json.api_format!(resources)` method to quickly represent a resource or collection in a valid [JSON API](http://jsonapi.org/) format without any new superclasses or weird setups. Set'n'go! :rocket:
4
+
5
+ ## Motivation
6
+
7
+ Official JSON API [implementations page](http://jsonapi.org/implementations/#server-libraries-ruby) shows us a variety of different serializers and other heavy-weight stuff. I' in love with [Jbuilder](https://github.com/rails/jbuilder), as it allows to format json responses with ease. Therefore I wanted to connect Jbuilder and JsonApi.org specs.
8
+
9
+ I'd like to notice that there already is one gem called [jbuilder-jsonapi](https://github.com/csexton/jbuilder-jsonapi) by [csexton](https://github.com/csexton), but it adds a links helper only. It's not enough for me! :facepunch:
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'jbuilder-json_api'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install jbuilder-json_api
26
+
27
+ ## Usage
28
+
29
+ Replace any content within any `*.json.jbuilder` file with the code below:
30
+ ```ruby
31
+ # Common example
32
+ json.api_format! @resources, @errors, meta: @meta, access_level: @user_access_level
33
+
34
+ # Articles w/o meta or access levels example
35
+ json.api_format! @articles, @errors
36
+ ```
37
+ You can also render formatted JSON straight from controller actions:
38
+ ```ruby
39
+ respond_to do |f|
40
+ f.json { render layout: false, json: JSON.parse(JbuilderTemplate.new(view_context).api_format!(@item).target!) }
41
+ f.html { render nothing: true, status: :bad_request }
42
+ end
43
+ ```
44
+ Each resource instance, as well as the included one, will be invoked with `json_api_attrs` & `json_api_relations` methods. These methods **MAY** be implemented within each model. `api_format!` method will try to get an object's permitted (**you are free do define authentication logic yourself!**) attributes and relations via those two methods.
45
+
46
+ Here is an example of implementation:
47
+ ```ruby
48
+ # Item model
49
+
50
+ def json_api_attr (access_level = nil)
51
+ attrs = []
52
+ attrs += %w(name description price buyoutable item_type category) if %i(user admin).include?access_level
53
+ attrs += %w(real_price in_stock) if access_level == :admin
54
+ attrs
55
+ end
56
+
57
+ def json_api_relations (access_level = nil)
58
+ %w(category orders)
59
+ end
60
+ ```
61
+ **Note** that the gem will call methods pulled with `json_api_relations and _attrs`. As for the above example, methods like `:name`, `:description`, `:orders` will be invoked for an Item instance. And yes, relations are fetched properly if an object responds to `orders`.
62
+
63
+ ## Development
64
+
65
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
66
+
67
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/vladfaust/jbuilder-json_api](https://github.com/vladfaust/jbuilder-json_api). It would be really good if someone contributes. :smile:
72
+
73
+ ## ToDo
74
+
75
+ - [ ] Maybe add `Content-Type: application/vnd.api+json`. This spec is ignored right now :smirk:
76
+ - [ ] Add links tests
77
+ - [ ] Somehow implement `[fields]` parameter
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ module JsonAPI
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,154 @@
1
+ require 'jbuilder'
2
+ require 'jbuilder/json_api/version'
3
+
4
+ module JsonAPI
5
+ # Returns a valid-formatted JSON which follows JSON-API specifications:
6
+ # http://jsonapi.org/
7
+ #
8
+ # Arguments:
9
+ # :resources: - list of resources to render (may be even one or nil)
10
+ # :errors: - array of errors in below format:
11
+ # [{ status: 422, detail: 'This error occurs because...' }, {...}]
12
+ #
13
+ # Options:
14
+ # :access_level: - access level, e.g. nil, :user, :admin
15
+ # :meta: - a hash representing meta (additional) information
16
+ #
17
+ def api_format! (resources = nil, errors = nil, options = {})
18
+ options.merge access_level: nil
19
+ options.merge meta: nil
20
+
21
+ # Firstly, print meta
22
+ # http://jsonapi.org/format/#document-meta
23
+ #
24
+ if options[:meta] && !options[:meta].empty?
25
+ meta options[:meta]
26
+ end
27
+
28
+ # Secondly, take care of errors. If there are any,
29
+ # no 'data' section should be represented.
30
+ # http://jsonapi.org/format/#document-top-level
31
+ #
32
+ # Read more at
33
+ # http://jsonapi.org/format/#errors
34
+ #
35
+ if errors && !errors.empty?
36
+ ignore_nil! (@ignore_nil.nil? ? true : @ignore_nil)
37
+ errors errors do |error|
38
+ id error[:id]
39
+ status error[:status]
40
+ detail error[:detail]
41
+ code error[:code]
42
+ title error[:title]
43
+
44
+ source do
45
+ pointer error[:pointer]
46
+ paramater error[:parameter]
47
+ end
48
+
49
+ links do
50
+ about error[:about]
51
+ end
52
+ end
53
+ return self
54
+ end
55
+
56
+ resources = ::Kernel::Array resources
57
+
58
+ # http://jsonapi.org/format/#document-links
59
+ #
60
+ links do
61
+ begin
62
+ set! 'self', @context.request.path
63
+ rescue
64
+ # No @context given, cannot find path
65
+ end
66
+ end
67
+
68
+ data do
69
+ resources.blank? ? array! : _api_resource_objects(resources, options[:access_level])
70
+ end
71
+
72
+ included = []
73
+ resources.each do |resource|
74
+ next unless resource.respond_to?'json_api_relations'
75
+ resource.json_api_relations(options[:access_level]).each do |relationship|
76
+ included += ::Kernel::Array(resource.send(relationship))
77
+ end
78
+ end
79
+ included.uniq!
80
+
81
+ included do
82
+ _api_resource_objects(included, options[:access_level], resources) unless included.blank?
83
+ end
84
+
85
+ self
86
+ end
87
+
88
+ private
89
+
90
+ # Formats a resources array properly
91
+ # http://jsonapi.org/format/#document-resource-objects
92
+ #
93
+ def _api_resource_objects (resources, access_level, parent_resources = nil)
94
+ resources.each do |resource|
95
+ child! do
96
+ type resource.class.name.demodulize.to_s.downcase
97
+ id resource.id
98
+
99
+ # http://jsonapi.org/format/#document-resource-object-attributes
100
+ #
101
+ if resource.respond_to?'json_api_attrs'
102
+ attributes do
103
+ resource.json_api_attrs(access_level).each do |attribute|
104
+ set! attribute, resource.send(attribute)
105
+ end
106
+ end
107
+ end
108
+
109
+ # http://jsonapi.org/format/#document-resource-object-relationships
110
+ #
111
+ if resource.respond_to?'json_api_relations'
112
+ unless resource.json_api_relations(access_level).blank?
113
+ relationships do
114
+ resource.json_api_relations(access_level).each do |relationship|
115
+ set! relationship do
116
+ links do
117
+ begin
118
+ related @context.send("#{ relationship.pluralize }_path")
119
+ rescue
120
+ # No @context given, cannot find path
121
+ end
122
+ # TODO add a link to the relationship itself
123
+ end
124
+
125
+ data do
126
+ ::Kernel::Array(resource.send(relationship)).each do |relationship_instance|
127
+ # Relationships shouldn't ever link to the parent resource
128
+ #
129
+ next if !parent_resources.nil? && parent_resources.include?(relationship_instance)
130
+ child! do
131
+ type relationship_instance.class.name.demodulize.to_s.downcase
132
+ id relationship_instance.id
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ links do
143
+ begin
144
+ set! 'self', @context.send("#{ resource.class.name.demodulize.to_s.downcase }_path", resource)
145
+ rescue
146
+ # No @context given, cannot find path
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ Jbuilder.include JsonAPI
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jbuilder-json_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vlad Faust
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jbuilder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.11'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.11'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_girl
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: codeclimate-test-reporter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Adds a method to build a valid JSON API (jsonapi.org) response without
98
+ any new superclasses or weird setups. Set'n'go!
99
+ email:
100
+ - vladislav.faust@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - README.md
106
+ - Rakefile
107
+ - lib/jbuilder/json_api.rb
108
+ - lib/jbuilder/json_api/version.rb
109
+ homepage: https://github.com/vladfaust/jbuilder-json_api
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.5.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Easily follow jsonapi.org specifications with Jbuilder
133
+ test_files: []