json_api_filter 0.2 → 0.3.2
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/gem-push.yml +31 -0
- data/Gemfile.lock +4 -4
- data/README.md +66 -5
- data/lib/json_api_filter/version.rb +1 -1
- data/lib/json_api_filter.rb +45 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5471c30a61e8ea40ce7e68b4ce5782c7a690bb9ec05db87b4945e43d1c0e1e0a
|
4
|
+
data.tar.gz: 8aea59cea05e034f6f33e8405fe1faa939fbf558887f704d296c7c6033b993b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4ef69f9954823df0f90f60f092c1bc948960096a7a61ddd16c8bc6d17f29eacf40a050ba9f203790ac5063a5868ce2f60a88fb2ed758117e0a000e74abe6ebd
|
7
|
+
data.tar.gz: 35d7ffff9ff7e409633e81701ead53db2ee8267fb54e768b4698c697a75c1ea5ff6afb4d66709713ea6765969b0eac35d88c70bd5f3279812d3f53ab8b11be93
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Build + Publish
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
contents: read
|
13
|
+
packages: write
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Set up Ruby 2.6
|
18
|
+
uses: actions/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.6.x
|
21
|
+
|
22
|
+
- name: Publish to RubyGems
|
23
|
+
run: |
|
24
|
+
mkdir -p $HOME/.gem
|
25
|
+
touch $HOME/.gem/credentials
|
26
|
+
chmod 0600 $HOME/.gem/credentials
|
27
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
28
|
+
gem build *.gemspec
|
29
|
+
gem push *.gem
|
30
|
+
env:
|
31
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
json_api_filter (0.2)
|
4
|
+
json_api_filter (0.3.2)
|
5
5
|
activesupport (>= 3.0.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -84,11 +84,11 @@ GEM
|
|
84
84
|
marcel (1.0.1)
|
85
85
|
method_source (1.0.0)
|
86
86
|
mini_mime (1.0.3)
|
87
|
-
mini_portile2 (2.
|
87
|
+
mini_portile2 (2.6.1)
|
88
88
|
minitest (5.14.4)
|
89
89
|
nio4r (2.5.7)
|
90
|
-
nokogiri (1.
|
91
|
-
mini_portile2 (~> 2.
|
90
|
+
nokogiri (1.12.5)
|
91
|
+
mini_portile2 (~> 2.6.1)
|
92
92
|
racc (~> 1.4)
|
93
93
|
racc (1.5.2)
|
94
94
|
rack (2.2.3)
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
Filter for rails controller based on JsonAPI spec: `/books?filter[library_id]=1,2&filter[author_id][eq]=12&filter[created_at][gt]=2021-02-02`
|
4
4
|
|
5
|
-
[](https://codeclimate.com/github/evalmee/json_api_filter/maintainability)
|
6
6
|
[](https://badge.fury.io/rb/json_api_filter)
|
7
|
-
[](https://travis-ci.com/evalmee/json_api_filter)
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -28,7 +28,7 @@ $ gem install json_api_filter
|
|
28
28
|
|
29
29
|
### Quick start
|
30
30
|
|
31
|
-
To filter this request `/books?filter[library_id]=1,2&filter[author_id]=12&search=Lord of the ring`
|
31
|
+
To filter this request `/books?filter[library_id]=1,2&filter[author_id]=12&search=Lord of the ring&include=users,users.posts`
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
class Book < ApplicationController
|
@@ -36,19 +36,80 @@ class Book < ApplicationController
|
|
36
36
|
include JsonApiFilter
|
37
37
|
permitted_filters %i[library_id author_id]
|
38
38
|
permitted_searches :user_search
|
39
|
-
|
39
|
+
permitted_inclusions %i[users users.posts]
|
40
|
+
|
40
41
|
def index
|
41
42
|
@books = json_api_filter(Book, params)
|
43
|
+
inclusions = json_api_inclusions(params) # returns [:users, :'users.posts']
|
44
|
+
|
45
|
+
# then use `inclusions` in the serialiser
|
46
|
+
BookSerializer.new(@books, include: inclusions).serializable_hash.to_json
|
42
47
|
end
|
43
|
-
|
44
48
|
end
|
45
49
|
|
46
50
|
```
|
47
51
|
|
48
52
|
- `permitted_filters` let you define allowed attributes to filter on (mandatory)
|
49
53
|
- `permitted_searches` let you define the allowed search method defined in you model what will be called if you pass `search` params in your request (can be a pg_search scope)
|
54
|
+
- `permitted_inclusions` let you define the allowed inclusions
|
50
55
|
- `json_api_filter(scope, params)` return an active record relation (`Book::` in this example)
|
56
|
+
|
57
|
+
# Use inclusions in serializers
|
58
|
+
|
59
|
+
# Handling errors
|
60
|
+
|
61
|
+
If an endpoint does not support the include parameter, it MUST respond with 400 Bad Request to any requests that include it.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class Book < ApplicationController
|
65
|
+
|
66
|
+
include JsonApiFilter
|
67
|
+
permitted_filters %i[library_id author_id]
|
68
|
+
permitted_searches :user_search
|
69
|
+
|
70
|
+
rescue_from JsonApiFilter::MissingPermittedInclusionError, with: :render_400
|
71
|
+
|
72
|
+
def index
|
73
|
+
@books = json_api_filter(Book, params)
|
74
|
+
inclusions = json_api_inclusions(params) # raises JsonApiFilter::MissingPermittedInclusionError
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
51
78
|
|
79
|
+
def render_400(exception)
|
80
|
+
render json: exception, status: 400
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
If a server is unable to identify a relationship path or does not support inclusion of resources from a path, it MUST respond with 400 Bad Request.
|
86
|
+
This request should return a 400 status:
|
87
|
+
|
88
|
+
`/books?filter[library_id]=1,2&filter[author_id]=12&search=Lord of the ring&include=users,users.posts, users.addresses`
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class Book < ApplicationController
|
92
|
+
|
93
|
+
include JsonApiFilter
|
94
|
+
permitted_filters %i[library_id author_id]
|
95
|
+
permitted_searches :user_search
|
96
|
+
permitted_inclusions %i[users users.posts]
|
97
|
+
|
98
|
+
rescue_from JsonApiFilter::UnknownInclusionsError, with: :render_400
|
99
|
+
|
100
|
+
def index
|
101
|
+
@books = json_api_filter(Book, params)
|
102
|
+
inclusions = json_api_inclusions(params) # raises JsonApiFilter::UnknownInclusionsError
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def render_400(exception)
|
108
|
+
render json: exception, status: 400
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
52
113
|
## Migration from 0.1
|
53
114
|
0.2.x version is not compatible with 0.1
|
54
115
|
In your controller, you will have to replace all occurrences of `attr_filter` as bellow :
|
data/lib/json_api_filter.rb
CHANGED
@@ -19,6 +19,24 @@ module JsonApiFilter
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
class MissingPermittedInclusionError < ::StandardError
|
23
|
+
def message
|
24
|
+
"PERMITTED_INCLUSIONS are required"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class UnknownInclusionsError < ::StandardError
|
29
|
+
attr_reader :item
|
30
|
+
def initialize(item)
|
31
|
+
super(message)
|
32
|
+
@item = item
|
33
|
+
end
|
34
|
+
|
35
|
+
def message
|
36
|
+
"Unable to identify #{item} as a relationship path or inclusion"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
extend ::ActiveSupport::Concern
|
23
41
|
included do
|
24
42
|
|
@@ -36,6 +54,17 @@ module JsonApiFilter
|
|
36
54
|
).process
|
37
55
|
end
|
38
56
|
|
57
|
+
def json_api_inclusions(params)
|
58
|
+
inclusions_params = params.fetch(:include, "").split(",").map(&:to_sym).uniq
|
59
|
+
unknown_inclusion = inclusions_params.find { |resource| json_api_permitted_inclusions.exclude?(resource) }
|
60
|
+
|
61
|
+
# If a server is unable to identify a relationship path or does not support inclusion of resources from a path,
|
62
|
+
# it MUST respond with 400 Bad Request.
|
63
|
+
raise UnknownInclusionsError, unknown_inclusion if unknown_inclusion.present?
|
64
|
+
|
65
|
+
inclusions_params
|
66
|
+
end
|
67
|
+
|
39
68
|
def self.permitted_filters(val)
|
40
69
|
define_singleton_method(:json_api_permitted_filters) do
|
41
70
|
val
|
@@ -55,5 +84,21 @@ module JsonApiFilter
|
|
55
84
|
def self.json_api_permitted_searches
|
56
85
|
{}
|
57
86
|
end
|
87
|
+
|
88
|
+
def self.permitted_inclusions(inclusions)
|
89
|
+
define_singleton_method(:json_api_permitted_inclusions) do
|
90
|
+
inclusions
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# If an endpoint does not support the include parameter,
|
95
|
+
# it MUST respond with 400 Bad Request to any requests that include it.
|
96
|
+
def self.json_api_permitted_inclusions
|
97
|
+
raise MissingPermittedInclusionError
|
98
|
+
end
|
99
|
+
|
100
|
+
def json_api_permitted_inclusions
|
101
|
+
self.class.json_api_permitted_inclusions
|
102
|
+
end
|
58
103
|
end
|
59
104
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_api_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blaked
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,6 +129,7 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
+
- ".github/workflows/gem-push.yml"
|
132
133
|
- ".gitignore"
|
133
134
|
- ".rspec"
|
134
135
|
- ".travis.yml"
|
@@ -175,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
176
|
- !ruby/object:Gem::Version
|
176
177
|
version: '0'
|
177
178
|
requirements: []
|
178
|
-
rubygems_version: 3.0.3
|
179
|
+
rubygems_version: 3.0.3.1
|
179
180
|
signing_key:
|
180
181
|
specification_version: 4
|
181
182
|
summary: Provide a filter for jsonAPI Controller in Rails
|