json_api_server 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|