easy-jsonapi 1.0.3 → 1.0.4
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 +4 -4
- data/.github/workflows/codecov.yml +1 -0
- data/.github/workflows/publish.yml +0 -3
- data/.travis.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +18 -14
- data/docs/UsingTheRequestObject.md +1 -1
- data/docs/UsingUserConfigurations.md +1 -1
- data/easy-jsonapi.gemspec +1 -1
- data/lib/easy/jsonapi/exceptions/headers_exceptions.rb +16 -16
- data/lib/easy/jsonapi/middleware.rb +8 -8
- data/lib/easy/jsonapi/request/query_param_collection.rb +9 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ba6257960cd5fce1e43183afd073ef8effb8de8a7fa2d162eed112948be93e4
|
4
|
+
data.tar.gz: 3f33c8373a9015e27a426a92d64c8939bbe8a7caabc7a2eb190c4a60d04135bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 496393be7c0e4f1bd1914c724ddb560e0439d048644c09d73093391a75a837956626c1f9ae077da993875a7ed72dde22abe117ad84be56afb6999a51461b4560
|
7
|
+
data.tar.gz: 5558d5124d369612ac2482d6a1bbb2e2fbf7e0c5b0cec9a5515fcf1bc93c20d2b098d1a016998eab0371730c67ee026381db7d66a15e7e8e97808fd62912d659
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,11 +5,13 @@
|
|
5
5
|
|
6
6
|
# easy-jsonapi
|
7
7
|
|
8
|
-
|
9
|
-

|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+

|
9
|
+

|
10
|
+

|
11
|
+

|
12
|
+

|
13
|
+

|
14
|
+
|
13
15
|
|
14
16
|
The gem that makes using [JSON:API](https://jsonapi.org/) ***EASY***!
|
15
17
|
|
@@ -19,9 +21,9 @@ Ever wanted the benefits of [JSONAPI](https://jsonapi.org/) without the learning
|
|
19
21
|
2. A `parser` to interact with requests in a typical Object-Oriented Fashion, providing convenient and efficient access to headers, query parameters, and document members.
|
20
22
|
3. A `validator` to check your serialized responses for [JSONAPI](https://jsonapi.org/) compliance.
|
21
23
|
|
22
|
-
With its only gem dependency being [Oj](https://github.com/ohler55/oj), ***easy-jsonapi*** is a lightweight, dependable tool, featuring comprehensive error messages and over 500 unit tests allowing developers to spend less time debugging and more time creating.
|
24
|
+
With its only gem dependency being [Oj](https://github.com/ohler55/oj), ***easy-jsonapi*** is a lightweight, dependable tool, featuring comprehensive error messages and over ***500 unit tests*** allowing developers to spend less time debugging and more time creating.
|
23
25
|
|
24
|
-
As a bonus, flexible user configurations can be added to the middleware providing custom screening on all requests or individual requests depending on the resource type of the endpoint and the
|
26
|
+
As a bonus, flexible user configurations can be added to the middleware providing custom screening on all requests or individual requests depending on the resource type of the endpoint and the user-defined document, header, or query param restrictions.
|
25
27
|
|
26
28
|
## Links
|
27
29
|
|
@@ -54,13 +56,15 @@ $ gem install easy-jsonapi
|
|
54
56
|
|
55
57
|
## Quick Start
|
56
58
|
|
57
|
-
|
59
|
+
***easy-jsonapi's*** 3 main use cases can be used together or separately, so to get started quickly, do any of the 3 below to begin enjoying the convenience of the library.
|
60
|
+
|
61
|
+
- Set up the middleware
|
58
62
|
|
59
63
|
```ruby
|
60
64
|
use JSONAPI::Middleware
|
61
65
|
```
|
62
66
|
|
63
|
-
|
67
|
+
- Parse the rack environment variable and get access to request components (assumes valid JSON:API requests -- use with middleware to ensure valid requests)
|
64
68
|
|
65
69
|
```ruby
|
66
70
|
j_req = JSONAPI::Parser.parse_request(env)
|
@@ -70,7 +74,7 @@ $ gem install easy-jsonapi
|
|
70
74
|
j_req.body.data.type # => "person"
|
71
75
|
```
|
72
76
|
|
73
|
-
|
77
|
+
- Validate your serialized JSON:API before returning it to your clients.
|
74
78
|
|
75
79
|
```ruby
|
76
80
|
begin
|
@@ -120,9 +124,9 @@ use JSONAPI::Middleware
|
|
120
124
|
|
121
125
|
### Functionality
|
122
126
|
|
123
|
-
The easy-jsonapi middleware can
|
127
|
+
The easy-jsonapi middleware can operate in development or production mode.
|
124
128
|
|
125
|
-
If `ENV['RACK_ENV']` is set to `:development` or not set at all, the middleware will be
|
129
|
+
If `ENV['RACK_ENV']` is set to `:development` or not set at all, the middleware will be operating in development mode.
|
126
130
|
|
127
131
|
When the middleware is in development mode it will raise an exception wherever it finds the http request to be non JSONAPI compliant.
|
128
132
|
|
@@ -137,7 +141,7 @@ If `ENV['RACK_ENV']` is set to something other than `:development`, then the mi
|
|
137
141
|
|
138
142
|
### User Configurations
|
139
143
|
|
140
|
-
***easy-jsonapi*** has a fair amount of flexibility when it comes to user configurations
|
144
|
+
***easy-jsonapi*** has a fair amount of flexibility when it comes to user configurations but also plenty of room for to add more features. To see the currently available configurations see [UsingUserConfigurations](https://github.com/Curatess/easy-jsonapi/blob/production/docs/UsingUserConfigurations.md) and to propose a new feature create a pull request or ticket on the [dev repository](https://github.com/Curatess/easy-jsonapi/tree/dev).
|
141
145
|
|
142
146
|
## Using the Request Parser
|
143
147
|
|
@@ -196,7 +200,7 @@ See the [rubydocs](https://rubydoc.info/github/Curatess/easy-jsonapi/proudction)
|
|
196
200
|
|
197
201
|
## Acknowledgements
|
198
202
|
|
199
|
-
The exception checking strategy for `JSONAPI::Exceptions::DocumentExceptions` and some
|
203
|
+
The exception checking strategy for `JSONAPI::Exceptions::DocumentExceptions` and some initial compliance checks are based off [jsonapi-parser](https://github.com/jsonapi-rb/jsonapi-parser). We would like to thank the [jsonapi-rb](https://github.com/jsonapi-rb) team for the document validation work and to all our contributors and users for the continuous support!
|
200
204
|
|
201
205
|
## Releases
|
202
206
|
|
@@ -69,6 +69,6 @@ j_req.body.jsonapi # The JSONAPI jsonapi member
|
|
69
69
|
j_req.body.to_s # serialized JSONAPI
|
70
70
|
j_req.body.to_h # ruby hash representation of JSONAPI
|
71
71
|
|
72
|
-
# NOTE: j_req.body.data returns a
|
72
|
+
# NOTE: j_req.body.data returns a resource or an array of resources depending on the request
|
73
73
|
j_req.body.data # JSONAPI::Document::Resource or [JSONAPI::Document::Resource]
|
74
74
|
```
|
@@ -17,7 +17,7 @@ use JSONAPI::Middleware do |config_manager|
|
|
17
17
|
end
|
18
18
|
```
|
19
19
|
|
20
|
-
To add restrictions to ALL requests use default global config included with the Config Manager:
|
20
|
+
To add restrictions to ALL requests use the default global config included with the Config Manager:
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
use JSONAPI::Middleware do |config_manager|
|
data/easy-jsonapi.gemspec
CHANGED
@@ -25,9 +25,9 @@ module JSONAPI
|
|
25
25
|
|
26
26
|
# Check http verb vs included headers
|
27
27
|
# @param env [Hash] The rack environment variable
|
28
|
-
def self.check_request(env, config_manager = nil, opts = {})
|
28
|
+
def self.check_request(env, body, config_manager = nil, opts = {})
|
29
29
|
check_compliance(env, config_manager, opts)
|
30
|
-
check_http_method_against_headers(env)
|
30
|
+
check_http_method_against_headers(env, body)
|
31
31
|
end
|
32
32
|
|
33
33
|
# Check jsonapi compliance
|
@@ -78,30 +78,30 @@ module JSONAPI
|
|
78
78
|
# error if the combination doesn't make sense
|
79
79
|
# @param (see #compliant?)
|
80
80
|
# @raise InvalidHeader the invalid header incombination with the http verb
|
81
|
-
def check_http_method_against_headers(env)
|
81
|
+
def check_http_method_against_headers(env, body)
|
82
82
|
case env['REQUEST_METHOD']
|
83
83
|
when 'GET'
|
84
|
-
check_get_against_hdrs(env)
|
84
|
+
check_get_against_hdrs(env, body)
|
85
85
|
when 'POST' || 'PATCH' || 'PUT'
|
86
|
-
check_post_against_hdrs(env)
|
86
|
+
check_post_against_hdrs(env, body)
|
87
87
|
when 'DELETE'
|
88
|
-
check_delete_against_hdrs(env)
|
88
|
+
check_delete_against_hdrs(env, body)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
# Raise error if a GET request has a body or a content type header
|
93
93
|
# @param (see #compliant?)
|
94
|
-
def check_get_against_hdrs(env)
|
95
|
-
raise_error('GET requests cannot have a body.') unless
|
94
|
+
def check_get_against_hdrs(env, body)
|
95
|
+
raise_error('GET requests cannot have a body.') unless body == ""
|
96
96
|
raise_error("GET request cannot have a 'CONTENT_TYPE' http header.") unless env['CONTENT_TYPE'].nil?
|
97
97
|
end
|
98
98
|
|
99
99
|
# POST, PUT, and PATCH request must have a content type header,
|
100
100
|
# a body, and a content-type and accept header that accepts jsonapi
|
101
101
|
# @param (see #compliant?)
|
102
|
-
def check_post_against_hdrs(env)
|
102
|
+
def check_post_against_hdrs(env, body)
|
103
103
|
raise_error("POST, PUT, and PATCH requests must have a 'CONTENT_TYPE' header.") unless env['CONTENT_TYPE']
|
104
|
-
raise_error('POST, PUT, and PATCH requests must have a body.')
|
104
|
+
raise_error('POST, PUT, and PATCH requests must have a body.') if body == ""
|
105
105
|
|
106
106
|
return if env['CONTENT_TYPE'] == 'application/vnd.api+json' && accepts_jsonapi?(env)
|
107
107
|
|
@@ -109,6 +109,12 @@ module JSONAPI
|
|
109
109
|
"JSON:API media type, if they include a JSON:API 'CONTENT_TYPE' header")
|
110
110
|
end
|
111
111
|
|
112
|
+
# Raise error if DELETE hdr has a body or a content type header
|
113
|
+
def check_delete_against_hdrs(env, body)
|
114
|
+
raise_error('DELETE requests cannot have a body.') unless body == ""
|
115
|
+
raise_error("DELETE request cannot have a 'CONTENT_TYPE' http header.") unless env['CONTENT_TYPE'].nil?
|
116
|
+
end
|
117
|
+
|
112
118
|
# Check the accept header to see if any of the provided media types indicate that
|
113
119
|
# jsonapi is accepted
|
114
120
|
# @param (see #compliant?)
|
@@ -121,12 +127,6 @@ module JSONAPI
|
|
121
127
|
false
|
122
128
|
end
|
123
129
|
|
124
|
-
# Raise error if DELETE hdr has a body or a content type header
|
125
|
-
def check_delete_against_hdrs(env)
|
126
|
-
raise_error('DELETE requests cannot have a body.') unless env['rack.input'].nil?
|
127
|
-
raise_error("DELETE request cannot have a 'CONTENT_TYPE' http header.") unless env['CONTENT_TYPE'].nil?
|
128
|
-
end
|
129
|
-
|
130
130
|
# @param accept_hdr [String] The value of the http accept header
|
131
131
|
def contains_at_least_one_jsonapi_media_type_without_params?(accept_hdr)
|
132
132
|
accept_hdr.split(',').each do |mt|
|
@@ -88,9 +88,12 @@ module JSONAPI
|
|
88
88
|
# @param config_manager [JSONAPI::ConfigManager::Config] The config object to use modify compliance checking
|
89
89
|
# @return [NilClass | Array] Nil meaning no error or a 400 level http response
|
90
90
|
def check_compliance(env, config_manager)
|
91
|
+
# Store separately so you can rewind for next middleware or app
|
92
|
+
body = env['rack.input'].read
|
93
|
+
env['rack.input'].rewind
|
91
94
|
opts = { http_method: env['REQUEST_METHOD'], path: env['PATH_INFO'] }
|
92
95
|
|
93
|
-
header_error = check_headers_compliance(env, config_manager, opts)
|
96
|
+
header_error = check_headers_compliance(env, body, config_manager, opts)
|
94
97
|
return header_error unless header_error.nil?
|
95
98
|
|
96
99
|
req = Rack::Request.new(env)
|
@@ -99,15 +102,15 @@ module JSONAPI
|
|
99
102
|
|
100
103
|
return unless env['CONTENT_TYPE']
|
101
104
|
|
102
|
-
body_error = check_req_body_compliance(env, config_manager, opts)
|
105
|
+
body_error = check_req_body_compliance(env, body, config_manager, opts)
|
103
106
|
return body_error unless body_error.nil?
|
104
107
|
end
|
105
108
|
|
106
109
|
# Checks whether the http headers are jsonapi compliant
|
107
110
|
# @param (see #call)
|
108
111
|
# @return [NilClass | Array] Nil meaning no error or a 400 level http response
|
109
|
-
def check_headers_compliance(env, config_manager, opts)
|
110
|
-
JSONAPI::Exceptions::HeadersExceptions.check_request(env, config_manager, opts)
|
112
|
+
def check_headers_compliance(env, body, config_manager, opts)
|
113
|
+
JSONAPI::Exceptions::HeadersExceptions.check_request(env, body, config_manager, opts)
|
111
114
|
rescue JSONAPI::Exceptions::HeadersExceptions::InvalidHeader || JSONAPI::Exceptions::UserDefinedExceptions::InvalidHeader => e
|
112
115
|
raise if environment_development?(env)
|
113
116
|
|
@@ -128,10 +131,7 @@ module JSONAPI
|
|
128
131
|
# @param env (see #call)
|
129
132
|
# @param req (see #check_query_param_compliance)
|
130
133
|
# @raise If the document body is not JSONAPI compliant
|
131
|
-
def check_req_body_compliance(env, config_manager, opts)
|
132
|
-
# Store separately so you can rewind for next middleware or app
|
133
|
-
body = env['rack.input'].read
|
134
|
-
env['rack.input'].rewind
|
134
|
+
def check_req_body_compliance(env, body, config_manager, opts)
|
135
135
|
JSONAPI::Exceptions::DocumentExceptions.check_compliance(body, config_manager, opts)
|
136
136
|
rescue JSONAPI::Exceptions::DocumentExceptions::InvalidDocument || JSONAPI::Exceptions::UserDefinedExceptions::InvalidDocument => e
|
137
137
|
raise if environment_development?(env)
|
@@ -8,10 +8,12 @@ module JSONAPI
|
|
8
8
|
# A collection of QueryParam objects
|
9
9
|
class QueryParamCollection < JSONAPI::NameValuePairCollection
|
10
10
|
|
11
|
+
# The special query params defined by the JSON:API specification
|
12
|
+
SPECIAL_QUERY_PARAMS = %i[sorts filters fields page includes].freeze
|
13
|
+
|
11
14
|
# @param param_arr [Array<JSONAPI::Request::QueryParamCollection::QueryParam] The
|
12
15
|
# query params to initialize the collection with
|
13
16
|
def initialize(param_arr = [])
|
14
|
-
@param_names = []
|
15
17
|
super(param_arr, item_type: JSONAPI::Request::QueryParamCollection::QueryParam)
|
16
18
|
end
|
17
19
|
|
@@ -43,8 +45,12 @@ module JSONAPI
|
|
43
45
|
# @param args If any arguments were passed to the method called
|
44
46
|
# @param block If a block was passed to the method called
|
45
47
|
def method_missing(method_name, *args, &block)
|
46
|
-
|
47
|
-
|
48
|
+
included = include?(method_name)
|
49
|
+
super unless included || SPECIAL_QUERY_PARAMS.include?(method_name)
|
50
|
+
if included
|
51
|
+
return get(method_name)
|
52
|
+
end
|
53
|
+
nil
|
48
54
|
end
|
49
55
|
|
50
56
|
# Whether or not method missing should be called.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy-jsonapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua DeMoss, Joe Viscomi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- ".rubocop.yml"
|
141
141
|
- ".ruby-gemset"
|
142
142
|
- ".ruby-version"
|
143
|
+
- ".travis.yml"
|
143
144
|
- CHANGELOG.md
|
144
145
|
- CODE_OF_CONDUCT.md
|
145
146
|
- Gemfile
|