json_api_server 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.
- checksums.yaml +7 -0
- data/.dockerignore +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.rubocop.yml +35 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Dockerfile +9 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +432 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/locales/en.yml +32 -0
- data/docker-compose.yml +10 -0
- data/json_api_server.gemspec +50 -0
- data/lib/json_api_server.rb +76 -0
- data/lib/json_api_server/api_version.rb +8 -0
- data/lib/json_api_server/attributes_builder.rb +135 -0
- data/lib/json_api_server/base_serializer.rb +169 -0
- data/lib/json_api_server/builder.rb +201 -0
- data/lib/json_api_server/cast.rb +89 -0
- data/lib/json_api_server/configuration.rb +99 -0
- data/lib/json_api_server/controller/error_handling.rb +164 -0
- data/lib/json_api_server/engine.rb +5 -0
- data/lib/json_api_server/error.rb +64 -0
- data/lib/json_api_server/errors.rb +50 -0
- data/lib/json_api_server/exceptions.rb +6 -0
- data/lib/json_api_server/fields.rb +76 -0
- data/lib/json_api_server/filter.rb +255 -0
- data/lib/json_api_server/filter_builders.rb +135 -0
- data/lib/json_api_server/filter_config.rb +71 -0
- data/lib/json_api_server/filter_parser.rb +88 -0
- data/lib/json_api_server/include.rb +158 -0
- data/lib/json_api_server/meta_builder.rb +39 -0
- data/lib/json_api_server/mime_types.rb +21 -0
- data/lib/json_api_server/pagination.rb +189 -0
- data/lib/json_api_server/paginator.rb +134 -0
- data/lib/json_api_server/relationships_builder.rb +215 -0
- data/lib/json_api_server/resource_serializer.rb +245 -0
- data/lib/json_api_server/resources_serializer.rb +131 -0
- data/lib/json_api_server/serializer.rb +34 -0
- data/lib/json_api_server/sort.rb +156 -0
- data/lib/json_api_server/sort_configs.rb +63 -0
- data/lib/json_api_server/validation_errors.rb +51 -0
- data/lib/json_api_server/version.rb +3 -0
- metadata +259 -0
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'json_api_server'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
en:
|
2
|
+
json_api_server:
|
3
|
+
variables:
|
4
|
+
defaults:
|
5
|
+
name: 'resource'
|
6
|
+
render_400:
|
7
|
+
title: 'Bad Request'
|
8
|
+
detail: "You've made an invalid request."
|
9
|
+
inclusion: "Inclusion param '%{param}' is not supported."
|
10
|
+
filter: "Filter param '%{param}' is not supported."
|
11
|
+
sort: "Sort param '%{param}' is not supported."
|
12
|
+
render_401:
|
13
|
+
title: 'Unauthorized'
|
14
|
+
detail: 'Authentication failed.'
|
15
|
+
render_403:
|
16
|
+
title: 'Forbidden'
|
17
|
+
detail: 'Unauthorized to access this resource or perform this action.'
|
18
|
+
render_404:
|
19
|
+
title: 'Not Found'
|
20
|
+
detail: "This %{name} does not exist."
|
21
|
+
render_409:
|
22
|
+
title: 'Conflict'
|
23
|
+
detail: "This %{name} already exists."
|
24
|
+
render_500:
|
25
|
+
title: 'Internal Server Error'
|
26
|
+
detail: 'The server encountered an unexpected error.'
|
27
|
+
render_503:
|
28
|
+
title: 'Service Unavailable'
|
29
|
+
detail: 'The service is unavailable. It may be under maintenance or preparing for maintenance.'
|
30
|
+
render_unknown_format:
|
31
|
+
title: 'Unknown Format'
|
32
|
+
detail: "Format %{name} is not supported for this endpoint."
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'json_api_server/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'json_api_server'
|
9
|
+
spec.version = JsonApiServer::VERSION
|
10
|
+
spec.authors = ['ed.mare']
|
11
|
+
|
12
|
+
spec.summary = 'Implements JSON API 1.0 - data, errors, meta, pagination, sort, ' \
|
13
|
+
'filters, sparse fieldsets and inclusion of related resources.'
|
14
|
+
spec.description = 'For building JSON APIs.'
|
15
|
+
spec.homepage = 'https://github.com/ed-mare/json_api_server'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
20
|
+
if spec.respond_to?(:metadata)
|
21
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
22
|
+
else
|
23
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
24
|
+
'public gem pushes.'
|
25
|
+
end
|
26
|
+
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
28
|
+
f.match(%r{^(test|spec|features)/})
|
29
|
+
end
|
30
|
+
spec.bindir = 'exe'
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ['lib']
|
33
|
+
spec.required_ruby_version = '>= 2.1'
|
34
|
+
|
35
|
+
spec.rdoc_options += ['--main', 'README.md', '--exclude', 'spec', '--exclude', 'bin', '--exclude', 'Dockerfile',
|
36
|
+
'--exclude', 'Gemfile', '--exclude', 'Gemfile.lock', '--exclude', 'Rakefile']
|
37
|
+
|
38
|
+
spec.add_dependency 'oj', '~> 3.0'
|
39
|
+
spec.add_dependency 'railties', '>= 5.0'
|
40
|
+
spec.add_dependency 'activesupport', '>= 5.0'
|
41
|
+
spec.add_dependency 'will_paginate', '~> 3.1.0' # for Rails 3+, Sinatra, and Merb
|
42
|
+
|
43
|
+
spec.add_development_dependency 'bundler', '>= 1.13'
|
44
|
+
spec.add_development_dependency 'sqlite3'
|
45
|
+
spec.add_development_dependency 'rake', '>= 10.0'
|
46
|
+
spec.add_development_dependency 'rspec', '>= 3.0'
|
47
|
+
spec.add_development_dependency 'rails', '>= 4.1'
|
48
|
+
spec.add_development_dependency 'rspec-rails', '>= 3.5'
|
49
|
+
spec.add_development_dependency 'rubocop', '>= 0.47'
|
50
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'oj'
|
2
|
+
require 'will_paginate'
|
3
|
+
require 'logger'
|
4
|
+
require 'active_support/core_ext/module/delegation'
|
5
|
+
require 'active_support/core_ext/object/blank'
|
6
|
+
require 'active_support/core_ext/object/try'
|
7
|
+
require 'active_support/core_ext/hash'
|
8
|
+
require 'active_support/inflector'
|
9
|
+
|
10
|
+
require 'json_api_server/version'
|
11
|
+
require 'json_api_server/api_version'
|
12
|
+
require 'json_api_server/exceptions'
|
13
|
+
require 'json_api_server/filter_builders'
|
14
|
+
require 'json_api_server/configuration'
|
15
|
+
require 'json_api_server/meta_builder'
|
16
|
+
require 'json_api_server/serializer'
|
17
|
+
require 'json_api_server/base_serializer'
|
18
|
+
require 'json_api_server/resource_serializer'
|
19
|
+
require 'json_api_server/resources_serializer'
|
20
|
+
require 'json_api_server/attributes_builder'
|
21
|
+
require 'json_api_server/relationships_builder'
|
22
|
+
require 'json_api_server/error'
|
23
|
+
require 'json_api_server/errors'
|
24
|
+
require 'json_api_server/validation_errors'
|
25
|
+
require 'json_api_server/paginator'
|
26
|
+
require 'json_api_server/pagination'
|
27
|
+
require 'json_api_server/sort_configs'
|
28
|
+
require 'json_api_server/sort'
|
29
|
+
require 'json_api_server/fields'
|
30
|
+
require 'json_api_server/cast'
|
31
|
+
require 'json_api_server/filter_config'
|
32
|
+
require 'json_api_server/filter_parser'
|
33
|
+
require 'json_api_server/filter'
|
34
|
+
require 'json_api_server/include'
|
35
|
+
require 'json_api_server/builder'
|
36
|
+
|
37
|
+
if defined?(Rails)
|
38
|
+
require 'json_api_server/engine'
|
39
|
+
require 'json_api_server/mime_types'
|
40
|
+
require 'json_api_server/controller/error_handling'
|
41
|
+
|
42
|
+
# https://github.com/ohler55/oj/blob/master/pages/Rails.md
|
43
|
+
# gem 'oj_mimic_json' # we need this for Rails 4.1.x
|
44
|
+
Oj.optimize_rails if Oj.respond_to?(:optimize_rails) # rails 5 but also rails 4?
|
45
|
+
end
|
46
|
+
|
47
|
+
module JsonApiServer # :nodoc:
|
48
|
+
class << self
|
49
|
+
attr_writer :configuration
|
50
|
+
|
51
|
+
def configuration
|
52
|
+
@configuration ||= JsonApiServer::Configuration.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def configure
|
56
|
+
yield configuration
|
57
|
+
end
|
58
|
+
|
59
|
+
def errors(errors)
|
60
|
+
JsonApiServer::Errors.new(errors)
|
61
|
+
end
|
62
|
+
|
63
|
+
def validation_errors(model)
|
64
|
+
JsonApiServer::ValidationErrors.new(model)
|
65
|
+
end
|
66
|
+
|
67
|
+
def paginator(current_page, total_pages, per_page, base_url, params = {})
|
68
|
+
JsonApiServer::Paginator.new(current_page, total_pages, per_page, base_url, params)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Convenience method to JsonApiServer.configuration.logger.
|
72
|
+
def logger
|
73
|
+
JsonApiServer.configuration.logger
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module JsonApiServer # :nodoc:
|
2
|
+
# Related to sparse fieldsets. http://jsonapi.org/format/#fetching-sparse-fieldsets
|
3
|
+
# "A client MAY request that an endpoint return only specific fields in the response on a per-type
|
4
|
+
# basis by including a fields[TYPE] parameter."
|
5
|
+
#
|
6
|
+
# Use this class to build the <tt>attributes</tt> section in JSON API
|
7
|
+
# serializers. It will only add attributes defined in #fields (sparse fieldset).
|
8
|
+
# If #fields is nil (no requested sparse fieldset), it will add all attributes.
|
9
|
+
#
|
10
|
+
# ==== Examples
|
11
|
+
#
|
12
|
+
# This:
|
13
|
+
# /articles?include=author&fields[articles]=title,body,phone&fields[people]=name
|
14
|
+
#
|
15
|
+
# converts to:
|
16
|
+
# {'articles' => ['title', 'body', 'phone'], 'people' => ['name']}
|
17
|
+
#
|
18
|
+
# When <tt>fields</tt> is an array, only fields in the array are added:
|
19
|
+
#
|
20
|
+
# AttributesBuilder.new(['title', 'body', 'phone'])
|
21
|
+
# .add('title', @record.title)
|
22
|
+
# .add('body', @record.body)
|
23
|
+
# .add_if('phone', @record.phone, -> { admin? }) # conditionally adding
|
24
|
+
# .add('isbn', @record.isbn) # not in sparse fields array
|
25
|
+
# .attributes
|
26
|
+
#
|
27
|
+
# # when non-admin
|
28
|
+
# # => {
|
29
|
+
# # 'title' => 'Everyone Poops',
|
30
|
+
# # 'body' => 'Taro Gomi'
|
31
|
+
# # }
|
32
|
+
#
|
33
|
+
# # or...
|
34
|
+
#
|
35
|
+
# # when admin
|
36
|
+
# # => {
|
37
|
+
# # 'title' => 'Everyone Poops',
|
38
|
+
# # 'body' => 'Taro Gomi',
|
39
|
+
# # 'phone' => '123-4567',
|
40
|
+
# # }
|
41
|
+
#
|
42
|
+
# When <tt>fields</tt> is nil, all attributes are added.
|
43
|
+
#
|
44
|
+
# AttributesBuilder.new
|
45
|
+
# .add_multi(@record, 'title', 'body')
|
46
|
+
# .add_if('phone', @record.phone, -> { admin? }) # conditionally adding
|
47
|
+
# .add('isbn', @record.isbn)
|
48
|
+
# .attributes
|
49
|
+
#
|
50
|
+
# # when non-admin
|
51
|
+
# # => {
|
52
|
+
# # 'title' => 'Everyone Poops',
|
53
|
+
# # 'body' => 'Taro Gomi',
|
54
|
+
# # 'isbn' => '5555555'
|
55
|
+
# # }
|
56
|
+
#
|
57
|
+
# # or...
|
58
|
+
#
|
59
|
+
# # when admin
|
60
|
+
# # => {
|
61
|
+
# # 'title' => 'Everyone Poops',
|
62
|
+
# # 'body' => 'Taro Gomi',
|
63
|
+
# # 'phone' => '123-4567',
|
64
|
+
# # 'isbn' => '5555555'
|
65
|
+
# # }
|
66
|
+
#
|
67
|
+
class AttributesBuilder
|
68
|
+
# (Array or nil) fields (sparse fieldset) array passed in initialize.
|
69
|
+
attr_reader :fields
|
70
|
+
|
71
|
+
# * <tt>fields</tt> - Array of fields to display for a type. Defaults to nil. When nil, all fields are permitted.
|
72
|
+
def initialize(fields = nil)
|
73
|
+
@hash = {}
|
74
|
+
@fields = fields
|
75
|
+
@fields.map!(&:to_s) if @fields.respond_to?(:map)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Adds attribute if attribute name is in <tt>fields</tt> array.
|
79
|
+
#
|
80
|
+
# i.e,
|
81
|
+
#
|
82
|
+
# JsonApiServer::AttributesBuilder.new(fields)
|
83
|
+
# .add('name', @object.name)
|
84
|
+
# .attributes
|
85
|
+
def add(name, value)
|
86
|
+
@hash[name.to_s] = value if add_attr?(name)
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
# Add multiple attributes.
|
91
|
+
#
|
92
|
+
# i.e,
|
93
|
+
#
|
94
|
+
# JsonApiServer::AttributesBuilder.new(fields)
|
95
|
+
# .add_multi(@object, 'name', 'email', 'logins')
|
96
|
+
# .attributes
|
97
|
+
def add_multi(object, *attrs)
|
98
|
+
attrs.each { |attr| add(attr, object.send(attr)) }
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
# Adds attribute if attribute name is in <tt>fields</tt> array *and* proc returns true.
|
103
|
+
#
|
104
|
+
# i.e,
|
105
|
+
#
|
106
|
+
# JsonApiServer::AttributesBuilder.new(fields)
|
107
|
+
# .add_if('email', @object.email, -> { admin? })
|
108
|
+
# .attributes
|
109
|
+
def add_if(name, value, proc)
|
110
|
+
@hash[name] = value if add_attr?(name) && proc.call == true
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns attributes as a hash.
|
115
|
+
#
|
116
|
+
# i.e.,
|
117
|
+
# {
|
118
|
+
# 'title' => 'Everyone Poops',
|
119
|
+
# 'body' => 'Taro Gomi',
|
120
|
+
# 'phone' => '123-4567',
|
121
|
+
# 'isbn' => '5555555'
|
122
|
+
# }
|
123
|
+
def attributes
|
124
|
+
@hash
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
129
|
+
# Returns true if @fields is not defined. If @fields is defined,
|
130
|
+
# returns true if attribute name is included in the @fields array.
|
131
|
+
def add_attr?(name)
|
132
|
+
@fields.respond_to?(:include?) ? @fields.include?(name.to_s) : true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module JsonApiServer # :nodoc:
|
2
|
+
# === Description
|
3
|
+
#
|
4
|
+
# Base JSON API serializer for this gem. Based on spec document structure:
|
5
|
+
# http://jsonapi.org/format/#document-structure. Classes should inherit and override.
|
6
|
+
# ResourceSerializer and ResourcesSerializer inherit from this class.
|
7
|
+
#
|
8
|
+
# Consists of 4 methods (#links, #data, #included, #meta) which create
|
9
|
+
# the following document structure. The 4 methods should return data
|
10
|
+
# that is serializable to JSON.
|
11
|
+
#
|
12
|
+
# {
|
13
|
+
# ":jsonapi": {
|
14
|
+
# ":version": "1.0"
|
15
|
+
# },
|
16
|
+
# ":links": null,
|
17
|
+
# ":data": null,
|
18
|
+
# ":included": null,
|
19
|
+
# ":meta": null
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
# There is an additional method, #relationship_data, which should be
|
23
|
+
# populated with data for "relationships".
|
24
|
+
#
|
25
|
+
# Example class:
|
26
|
+
#
|
27
|
+
# class CommentSerializer < JsonApiServer::BaseSerializer
|
28
|
+
# def initialize(object, **options)
|
29
|
+
# super(options)
|
30
|
+
# @object = object
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# def links
|
34
|
+
# {
|
35
|
+
# self: File.join(base_url, "/comments/#{@object.id}")
|
36
|
+
# }
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def data
|
40
|
+
# {
|
41
|
+
# "type": "comments",
|
42
|
+
# "id": "12",
|
43
|
+
# "attributes": {
|
44
|
+
# "comment": @object.comment,
|
45
|
+
# "created_at": @object.created_at,
|
46
|
+
# "updated_at": @object.created_at,
|
47
|
+
# },
|
48
|
+
# "relationships": {
|
49
|
+
# "author": {
|
50
|
+
# "links": {"self": "http://example.com/people/#{@object.author_id}"},
|
51
|
+
# "data": {"id": @object.author_id, "type": "people"}
|
52
|
+
# }
|
53
|
+
# }
|
54
|
+
# }
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# Sometimes only part of document is needed, i.e., when embedding one serializer in another.
|
59
|
+
# <tt>as_json</tt> takes an optional hash argument which determines which parts of the document to return.
|
60
|
+
# These options can also be set in the #as_json_options attribute.
|
61
|
+
#
|
62
|
+
# serializer.as_json(include: [:data]) # => { data: {...} }
|
63
|
+
# serializer.as_json(include: [:links]) # => { links: {...} }
|
64
|
+
# serializer.as_json(include: [:data, :links]) # =>
|
65
|
+
# # {
|
66
|
+
# # links: {...},
|
67
|
+
# # data: {...}
|
68
|
+
# # }
|
69
|
+
# serializer.as_json(include: [:relationship_data]) # =>
|
70
|
+
# # {
|
71
|
+
# # data: {
|
72
|
+
# # # usually links or object_id + type.
|
73
|
+
# # }
|
74
|
+
# # }
|
75
|
+
#
|
76
|
+
# <tt>base_url</tt> -- is JsonApiServer::Configuration#base_url exposed as a protected
|
77
|
+
# method. For creating links.
|
78
|
+
class BaseSerializer
|
79
|
+
include JsonApiServer::Serializer
|
80
|
+
include JsonApiServer::ApiVersion
|
81
|
+
|
82
|
+
# Hash. as_json options. Same options can be passed into #as_json.
|
83
|
+
# Defaults to nil. When not set, all sections are rendered.
|
84
|
+
#
|
85
|
+
# Possible options:
|
86
|
+
#
|
87
|
+
# <tt>:include</tt> (Array) -- Optional. Possible values: :jsonapi, :links, :data,
|
88
|
+
# :included, :meta and :relationship_data. :relationship_data is a special case --
|
89
|
+
# if present in the array, only relationship data is rendered (data section w/o
|
90
|
+
# attributes).
|
91
|
+
#
|
92
|
+
# i.e,
|
93
|
+
#
|
94
|
+
# # Set attribute
|
95
|
+
# serializer.as_json_options = { include: [:data] }
|
96
|
+
# serializer.as_json_options = { include: [:data, :links] }
|
97
|
+
# serializer.as_json_options = { include: [:relationship_data] }
|
98
|
+
#
|
99
|
+
# # Or set when calling #as_json
|
100
|
+
# serializer.as_json(include: [:data])
|
101
|
+
attr_accessor :as_json_options
|
102
|
+
|
103
|
+
def initialize(**options)
|
104
|
+
@as_json_options = options[:as_json_options]
|
105
|
+
end
|
106
|
+
|
107
|
+
# JSON API *links* section. Subclass implements.
|
108
|
+
# Api spec: http://jsonapi.org/format/#document-links
|
109
|
+
def links
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
# JSON API *data* section. Subclass implements.
|
114
|
+
# Api spec: http://jsonapi.org/format/#document-structure
|
115
|
+
def data
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# JSON to render with #as_json_option :relationship_data. Subclass implements.
|
120
|
+
# Api spec: http://jsonapi.org/format/#fetching-relationships
|
121
|
+
def relationship_data
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
|
125
|
+
# JSON API *included* section. Sublclass implements.
|
126
|
+
# Api spec: http://jsonapi.org/format/#fetching-includes
|
127
|
+
def included
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
# JSON API *meta* section. Sublclass implements.
|
132
|
+
# Api spec: http://jsonapi.org/format/#document-meta
|
133
|
+
def meta
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
|
137
|
+
# Creates the following document structure by default. See #as_json_options for
|
138
|
+
# a description of options. The hash is with indifferent access.
|
139
|
+
# {
|
140
|
+
# "jsonapi" => {
|
141
|
+
# "version" => "1.0"
|
142
|
+
# },
|
143
|
+
# "links" => null,
|
144
|
+
# "data" => null,
|
145
|
+
# "included" => null,
|
146
|
+
# "meta" => null
|
147
|
+
# }
|
148
|
+
def as_json(**options)
|
149
|
+
opts = (options.any? ? options : as_json_options) || {}
|
150
|
+
sections = opts[:include] || %w[jsonapi links data included meta]
|
151
|
+
hash = {}
|
152
|
+
|
153
|
+
if sections.include?(:relationship_data)
|
154
|
+
hash['data'] = relationship_data
|
155
|
+
else
|
156
|
+
sections.each { |s| hash[s] = send(s) if sections.include?(s) }
|
157
|
+
end
|
158
|
+
|
159
|
+
ActiveSupport::HashWithIndifferentAccess.new(hash)
|
160
|
+
end
|
161
|
+
|
162
|
+
protected
|
163
|
+
|
164
|
+
# Configuration base_url.
|
165
|
+
def base_url
|
166
|
+
JsonApiServer.configuration.base_url
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|