infinum_json_api_setup 0.0.7 → 0.1.0
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/test.yml +45 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +50 -12
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -0
- data/README.md +8 -0
- data/Rakefile +3 -0
- data/base.gemfile +14 -0
- data/infinum_json_api_setup.gemspec +11 -16
- data/lib/generators/infinum_json_api_setup/templates/config/locales/json_api.en.yml +1 -0
- data/lib/infinum_json_api_setup/json_api/content_negotiation.rb +2 -2
- data/lib/infinum_json_api_setup/json_api/locale_negotiation.rb +45 -0
- data/lib/infinum_json_api_setup/json_api/serializer_options.rb +1 -1
- data/lib/infinum_json_api_setup/rspec/helpers/response_helper.rb +4 -4
- data/lib/infinum_json_api_setup/rspec/matchers/have_empty_data.rb +1 -1
- data/lib/infinum_json_api_setup/rspec/matchers/have_error_pointer.rb +1 -1
- data/lib/infinum_json_api_setup/rspec/matchers/have_resource_count_of.rb +1 -1
- data/lib/infinum_json_api_setup/version.rb +1 -1
- data/lib/infinum_json_api_setup.rb +3 -0
- data/rails.7.1.gemfile +8 -0
- data/rails.7.1.gemfile.lock +361 -0
- data/rails.8.0.gemfile +7 -0
- data/rails.8.0.gemfile.lock +380 -0
- data/spec/dummy/app/controllers/api/v1/base_controller.rb +1 -0
- data/spec/dummy/app/controllers/api/v1/hello_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/v1/locations_controller.rb +7 -13
- data/spec/dummy/app/models/location.rb +1 -1
- data/spec/dummy/config/database.yml +3 -0
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/initializers/i18n.rb +3 -0
- data/spec/dummy/config/locales/de.yml +2 -0
- data/spec/dummy/config/locales/json_api.de.yml +22 -0
- data/spec/dummy/config/locales/json_api.en.yml +1 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/infinum_json_api_setup/rspec/helpers/response_helper_spec.rb +234 -0
- data/spec/infinum_json_api_setup/rspec/matchers/have_empty_data_spec.rb +3 -2
- data/spec/rails_helper.rb +2 -6
- data/spec/requests/api/v1/content_negotiation_spec.rb +10 -2
- data/spec/requests/api/v1/error_handling_spec.rb +37 -19
- data/spec/requests/api/v1/locale_negotiation_spec.rb +66 -0
- data/spec/requests/api/v1/responder_spec.rb +1 -1
- data/spec/requests/api/v1/serializer_options_spec.rb +1 -1
- metadata +46 -99
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -268
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd0a0f31918bb2f7f2c2fd1c89c7ef8704292bba7590c980c54ac8daa809c321
|
|
4
|
+
data.tar.gz: afb709b1deeb7891a4f7a65a248ffaebcbd4f0ad874e48d1c7c21dae623d3cb1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4c5c8b5f7564d095d43efa4a292263dc8c5cc65c4066f5ee3078b7b7afefcbb4879570ec6474ae6aa690a775afbd97f319ce6d6d3c55585314bbf455a0a5ce8
|
|
7
|
+
data.tar.gz: 60da19ebe9c6ebc6edf1fba046621cd966ecb5c4a0436fcc251ac5a18a946e6323a7f5359fc11632a434abfc886cf61eea7c256b364eccb2319a29eac0bfd0c8
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
services:
|
|
10
|
+
database:
|
|
11
|
+
image: postgres:14
|
|
12
|
+
env:
|
|
13
|
+
POSTGRES_HOST_AUTH_METHOD: trust
|
|
14
|
+
ports:
|
|
15
|
+
- 5432:5432
|
|
16
|
+
options: >-
|
|
17
|
+
--health-cmd pg_isready
|
|
18
|
+
--health-interval 10s
|
|
19
|
+
--health-timeout 5s
|
|
20
|
+
--health-retries 5
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
ruby: ['3.2.9', '3.3.9', '3.4.5']
|
|
25
|
+
gemfile: ['rails.7.1.gemfile', 'rails.8.0.gemfile']
|
|
26
|
+
env:
|
|
27
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v2
|
|
30
|
+
- name: Set up Ruby
|
|
31
|
+
uses: ruby/setup-ruby@v1
|
|
32
|
+
with:
|
|
33
|
+
ruby-version: "${{ matrix.ruby }}"
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: bundle install
|
|
36
|
+
- name: Setup database
|
|
37
|
+
env:
|
|
38
|
+
BUNDLE_GEMFILE: "../../${{ matrix.gemfile }}"
|
|
39
|
+
run: |
|
|
40
|
+
cd spec/dummy
|
|
41
|
+
bundle exec rake db:test:prepare
|
|
42
|
+
- name: Run rubocop
|
|
43
|
+
run: bundle exec rubocop
|
|
44
|
+
- name: Run specs
|
|
45
|
+
run: bundle exec rspec
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.4.5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
- fix runtime depenency loading
|
|
1
|
+
# Change Log for infinum/infinum-json-api-setup
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
- update installation instructions in README
|
|
8
|
-
- promote jsonapi-query-builder and jsonapi-serializer to runtime dependencies
|
|
9
|
-
- start CHANGELOG
|
|
5
|
+
This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a CHANGELOG](https://keepachangelog.com/).
|
|
10
6
|
|
|
11
|
-
[
|
|
7
|
+
## [Unreleased]
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
- bump jsonapi-query_builder dependency
|
|
15
|
-
- bump Nokogiri dependency (due to CVE)
|
|
9
|
+
### Changes
|
|
16
10
|
|
|
17
|
-
[
|
|
11
|
+
## [0.1.0] - 2025-11-03
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Rails 8 support
|
|
15
|
+
- Locale negotiation
|
|
16
|
+
|
|
17
|
+
### Changes
|
|
18
|
+
- Reformat CHANGELOG according to infinum/open-source-project-template
|
|
19
|
+
- Drop support for Rails 6.1
|
|
20
|
+
- Relax json_schemer dependency
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Ruby 3.4 ostruct deprecation warning
|
|
24
|
+
|
|
25
|
+
## [0.0.8] - 2021-10-25
|
|
26
|
+
|
|
27
|
+
### Updated
|
|
28
|
+
- Bump pagy dependency
|
|
29
|
+
|
|
30
|
+
## [0.0.7] - 2021-10-25
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- Runtime depenency loading
|
|
34
|
+
|
|
35
|
+
## [0.0.6] - 2021-10-25
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- CHANGELOG
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- Update installation instructions in README
|
|
42
|
+
- Promote jsonapi-query-builder and jsonapi-serializer to runtime dependencies
|
|
43
|
+
|
|
44
|
+
## [0.0.5] - 2021-10-06
|
|
45
|
+
|
|
46
|
+
### Updated
|
|
47
|
+
- Bump jsonapi-query_builder dependency
|
|
48
|
+
- Bump Nokogiri dependency (due to CVE)
|
|
49
|
+
|
|
50
|
+
[Unreleased]: https://github.com/infinum/infinum-json-api-setup/compare/v0.1.0...HEAD
|
|
51
|
+
[0.1.0]: https://github.com/infinum/infinum-json-api-setup/compare/v0.0.8...v0.1.0
|
|
52
|
+
[0.0.8]: https://github.com/infinum/infinum-json-api-setup/compare/v0.0.7...v0.0.8
|
|
53
|
+
[0.0.7]: https://github.com/infinum/infinum-json-api-setup/compare/v0.0.6...v0.0.7
|
|
54
|
+
[0.0.6]: https://github.com/infinum/infinum-json-api-setup/compare/v0.0.5...v0.0.6
|
|
55
|
+
[0.0.5]: https://github.com/infinum/infinum-json-api-setup/compare/v0.0.4...v0.0.5
|
data/Gemfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rails.7.1.gemfile
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rails.7.1.gemfile.lock
|
data/README.md
CHANGED
|
@@ -24,6 +24,7 @@ module Api
|
|
|
24
24
|
class BaseController < ActionController::API
|
|
25
25
|
include InfinumJsonApiSetup::JsonApi::ErrorHandling
|
|
26
26
|
include InfinumJsonApiSetup::JsonApi::ContentNegotiation
|
|
27
|
+
include InfinumJsonApiSetup::JsonApi::LocaleNegotiation
|
|
27
28
|
|
|
28
29
|
self.responder = InfinumJsonApiSetup::JsonApi::Responder
|
|
29
30
|
respond_to :json_api
|
|
@@ -71,6 +72,13 @@ This section explains the under-the-hood behavior of the library.
|
|
|
71
72
|
### Content negotiation
|
|
72
73
|
`InfinumJsonApiSetup::JsonApi::ContentNegotiation` module is designed to integrate [server responsibilities](https://jsonapi.org/format/#content-negotiation-servers) of content negotiation protocol described by the JSON:API specification.
|
|
73
74
|
|
|
75
|
+
### Locale negotiation
|
|
76
|
+
`InfinumJsonApiSetup::JsonApi::LocaleNegotiation` module ensures that request handling happens within the locale best matching the `Accept-Language` header.
|
|
77
|
+
|
|
78
|
+
- **Default behavior:** locale falls back to the application's default when the header is missing.
|
|
79
|
+
- **Invalid locales:** enable graceful fallback by setting `self.fallback_to_default_locale_if_invalid = true` in your controller when you want to disregard unrecognized locales instead of raising `json_api.errors.bad_request.invalid_locale`.
|
|
80
|
+
- **Error handling:** when fallback is disabled (default), requests with invalid locales trigger a JSON:API formatted bad request response.
|
|
81
|
+
|
|
74
82
|
### Error handling
|
|
75
83
|
`InfinumJsonApiSetup::JsonApi::ErrorHandling` module is designed to catch and handle common exceptions that might bubble up when processing a request.
|
|
76
84
|
|
data/Rakefile
CHANGED
data/base.gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'bundler-audit', require: false
|
|
4
|
+
gem 'factory_bot', '~> 6.2'
|
|
5
|
+
gem 'faker', '~> 2.18'
|
|
6
|
+
gem 'overcommit', '~> 0.58', require: false
|
|
7
|
+
gem 'pg'
|
|
8
|
+
gem 'pry-rails'
|
|
9
|
+
gem 'pundit'
|
|
10
|
+
gem 'rake', require: false
|
|
11
|
+
gem 'rubocop', '~> 1.0', require: false
|
|
12
|
+
gem 'rubocop-infinum', require: false
|
|
13
|
+
gem 'rubocop-rake', require: false
|
|
14
|
+
gem 'simplecov', require: false
|
|
@@ -10,21 +10,16 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.files = `git ls-files`.split("\n")
|
|
11
11
|
s.homepage = 'https://github.com/infinum/infinum-json-api-setup'
|
|
12
12
|
s.license = 'MIT'
|
|
13
|
-
s.required_ruby_version = '
|
|
13
|
+
s.required_ruby_version = '>= 3.2'
|
|
14
|
+
s.metadata = { 'rubygems_mfa_required' => 'true' }
|
|
14
15
|
|
|
15
|
-
s.
|
|
16
|
-
s.
|
|
17
|
-
s.
|
|
18
|
-
s.
|
|
19
|
-
s.
|
|
20
|
-
s.
|
|
21
|
-
s.
|
|
22
|
-
|
|
23
|
-
s.
|
|
24
|
-
s.add_development_dependency 'pg'
|
|
25
|
-
s.add_development_dependency 'pry-rails'
|
|
26
|
-
s.add_development_dependency 'pundit'
|
|
27
|
-
s.add_development_dependency 'rake'
|
|
28
|
-
s.add_development_dependency 'rspec-rails', '~> 5.0'
|
|
29
|
-
s.add_development_dependency 'simplecov'
|
|
16
|
+
s.add_dependency 'accept_language', '~> 2.0'
|
|
17
|
+
s.add_dependency 'jsonapi_parameters'
|
|
18
|
+
s.add_dependency 'jsonapi-query_builder'
|
|
19
|
+
s.add_dependency 'jsonapi-serializer'
|
|
20
|
+
s.add_dependency 'json_schemer', '>= 0.2', '< 3'
|
|
21
|
+
s.add_dependency 'ostruct'
|
|
22
|
+
s.add_dependency 'pagy', '~> 8.0'
|
|
23
|
+
s.add_dependency 'rails'
|
|
24
|
+
s.add_dependency 'responders'
|
|
30
25
|
end
|
|
@@ -16,9 +16,9 @@ module InfinumJsonApiSetup
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def valid_content_type?
|
|
19
|
-
return true if request.body.size.zero?
|
|
19
|
+
return true if request.body.nil? || request.body.size.zero? # rubocop:disable Style/ZeroLengthPredicate
|
|
20
20
|
|
|
21
|
-
request.
|
|
21
|
+
request.content_mime_type == Mime.fetch(:json_api)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def acceptable?
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module InfinumJsonApiSetup
|
|
2
|
+
module JsonApi
|
|
3
|
+
module LocaleNegotiation
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
around_action :setup_locale
|
|
8
|
+
class_attribute :fallback_to_default_locale_if_invalid, default: false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def rescue_with_handler(*)
|
|
12
|
+
I18n.with_locale(locale) { super }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def setup_locale(&)
|
|
18
|
+
return render_invalid_locale_error if locale.blank?
|
|
19
|
+
|
|
20
|
+
I18n.with_locale(locale, &)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def locale
|
|
24
|
+
return I18n.default_locale if locale_from_request.blank?
|
|
25
|
+
|
|
26
|
+
parsed_locale = AcceptLanguage.parse(locale_from_request).match(*I18n.available_locales)
|
|
27
|
+
|
|
28
|
+
if parsed_locale.present?
|
|
29
|
+
parsed_locale
|
|
30
|
+
elsif fallback_to_default_locale_if_invalid
|
|
31
|
+
I18n.default_locale
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def locale_from_request
|
|
36
|
+
request.env['HTTP_ACCEPT_LANGUAGE']
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def render_invalid_locale_error
|
|
40
|
+
message = I18n.t('json_api.errors.bad_request.invalid_locale')
|
|
41
|
+
render_error(InfinumJsonApiSetup::Error::BadRequest.new(message:))
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -33,7 +33,7 @@ module InfinumJsonApiSetup
|
|
|
33
33
|
total_count: pagination_details.count,
|
|
34
34
|
padding: pagination_details.vars.fetch(:outset).to_i,
|
|
35
35
|
page_size: pagination_details.vars.fetch(:items).to_i,
|
|
36
|
-
max_page_size: Pagy::
|
|
36
|
+
max_page_size: Pagy::DEFAULT[:max_items]
|
|
37
37
|
}
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -9,14 +9,14 @@ module InfinumJsonApiSetup
|
|
|
9
9
|
def response_item
|
|
10
10
|
raise 'json response is not an item' if json_response[:data].is_a?(Array)
|
|
11
11
|
|
|
12
|
-
OpenStruct.new(json_response[:data][:attributes])
|
|
12
|
+
OpenStruct.new(json_response[:data][:attributes]) # rubocop:disable Style/OpenStructUse
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def response_collection
|
|
16
16
|
raise 'json response is not a collection' unless json_response[:data].is_a?(Array)
|
|
17
17
|
|
|
18
18
|
json_response[:data].map do |item|
|
|
19
|
-
OpenStruct.new(id: item[:id], type: item[:type], **item[:attributes])
|
|
19
|
+
OpenStruct.new(id: item[:id], type: item[:type], **item[:attributes]) # rubocop:disable Style/OpenStructUse
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ module InfinumJsonApiSetup
|
|
|
24
24
|
case response_type
|
|
25
25
|
when :item then json_response.dig(:data, :relationships)
|
|
26
26
|
when :collection then json_response[:data].pluck(:relationships)
|
|
27
|
-
else raise ArgumentError ':response_type must be one of [:item, :collection]'
|
|
27
|
+
else raise ArgumentError, ':response_type must be one of [:item, :collection]'
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -34,7 +34,7 @@ module InfinumJsonApiSetup
|
|
|
34
34
|
|
|
35
35
|
def response_included
|
|
36
36
|
json_response[:included].map do |item|
|
|
37
|
-
OpenStruct.new(id: item[:id], type: item[:type], **item[:attributes])
|
|
37
|
+
OpenStruct.new(id: item[:id], type: item[:type], **item[:attributes]) # rubocop:disable Style/OpenStructUse
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -2,7 +2,7 @@ module InfinumJsonApiSetup
|
|
|
2
2
|
module RSpec
|
|
3
3
|
module Matchers
|
|
4
4
|
# @return [InfinumJsonApiSetup::Rspec::Matchers::HaveEmptyData]
|
|
5
|
-
def have_empty_data # rubocop:disable Naming/
|
|
5
|
+
def have_empty_data # rubocop:disable Naming/PredicatePrefix
|
|
6
6
|
HaveEmptyData.new
|
|
7
7
|
end
|
|
8
8
|
|
|
@@ -3,7 +3,7 @@ module InfinumJsonApiSetup
|
|
|
3
3
|
module Matchers
|
|
4
4
|
# @param [String] pointer
|
|
5
5
|
# @return [InfinumJsonApiSetup::Rspec::Matchers::HaveErrorPointer]
|
|
6
|
-
def have_error_pointer(pointer) # rubocop:disable Naming/
|
|
6
|
+
def have_error_pointer(pointer) # rubocop:disable Naming/PredicatePrefix
|
|
7
7
|
HaveErrorPointer.new(pointer)
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ module InfinumJsonApiSetup
|
|
|
3
3
|
module Matchers
|
|
4
4
|
# @param [Integer] expected_count
|
|
5
5
|
# @return [InfinumJsonApiSetup::Rspec::Matchers::HaveResourceCountOf]
|
|
6
|
-
def have_resource_count_of(expected_count) # rubocop:disable Naming/
|
|
6
|
+
def have_resource_count_of(expected_count) # rubocop:disable Naming/PredicatePrefix
|
|
7
7
|
HaveResourceCountOf.new(expected_count)
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
require 'rails'
|
|
2
2
|
|
|
3
|
+
require 'accept_language'
|
|
3
4
|
require 'json'
|
|
4
5
|
require 'jsonapi_parameters'
|
|
5
6
|
require 'jsonapi/serializer'
|
|
6
7
|
require 'json_schemer'
|
|
8
|
+
require 'ostruct'
|
|
7
9
|
require 'responders'
|
|
8
10
|
|
|
9
11
|
require 'pagy'
|
|
@@ -14,6 +16,7 @@ require 'infinum_json_api_setup/json_api/error_handling'
|
|
|
14
16
|
require 'infinum_json_api_setup/json_api/error_serializer'
|
|
15
17
|
|
|
16
18
|
require 'infinum_json_api_setup/json_api/content_negotiation'
|
|
19
|
+
require 'infinum_json_api_setup/json_api/locale_negotiation'
|
|
17
20
|
require 'infinum_json_api_setup/json_api/request_parsing'
|
|
18
21
|
require 'infinum_json_api_setup/json_api/serializer_options'
|
|
19
22
|
require 'infinum_json_api_setup/json_api/responder'
|