json_api_filter 0.2 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Maintainability](https://api.codeclimate.com/v1/badges/
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/92a4a44d4af2bfa3b27d/maintainability)](https://codeclimate.com/github/evalmee/json_api_filter/maintainability)
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/json_api_filter.svg)](https://badge.fury.io/rb/json_api_filter)
|
7
|
-
[![Build Status](https://travis-ci.com/
|
7
|
+
[![Build Status](https://travis-ci.com/evalmee/json_api_filter.svg?branch=master)](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
|