easy-jsonapi 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![](https://ruby-gem-downloads-badge.herokuapp.com/easy-jsonapi?type=total&color=brightgreen)
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
![Gem Version](https://badge.fury.io/rb/easy-jsonapi.svg)
|
9
|
+
![Downloads](https://ruby-gem-downloads-badge.herokuapp.com/easy-jsonapi?type=total&color=brightgreen)
|
10
|
+
![Build Status](https://img.shields.io/travis/Curatess/easy-jsonapi/production)
|
11
|
+
![Code Coverage](https://img.shields.io/codecov/c/github/curatess/easy-jsonapi)
|
12
|
+
![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)
|
13
|
+
![License](https://img.shields.io/github/license/Curatess/easy-jsonapi)
|
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
|