Skip to content

Commit c4cd97a

Browse files
authored
Merge pull request JsonApiClient#4 from residently/update-to-latest-upstream
Update to latest upstream
2 parents f0c3f15 + 65d6c20 commit c4cd97a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2073
-97
lines changed

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@ Gemfile.lock
2424
*.gemfile.lock
2525

2626
/coverage
27-
.idea/*
27+
28+
# IntellJ/RubyMine
29+
*.iml
30+
.idea/
31+
32+
# asdf config
33+
.tool-versions

.travis.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ rvm:
33
- 2.2.6
44
- 2.3.3
55
- 2.4.1
6+
- 2.5.1
7+
- 2.6.0
68
env:
79
global:
810
- CODECLIMATE_REPO_TOKEN=396d4263adb6febf1e6e9b0c0e176fbde35e1a116a3c1ecf8dd4f9384e41979b
@@ -12,9 +14,15 @@ gemfile:
1214
- gemfiles/4.1.gemfile
1315
- gemfiles/4.2.gemfile
1416
- gemfiles/5.0.gemfile
17+
- gemfiles/5.2.3.gemfile
18+
- gemfiles/6.0.gemfile
1519
matrix:
1620
fast_finish: true
1721
exclude:
22+
- rvm: 2.2.6
23+
gemfile: gemfiles/6.0.gemfile
24+
- rvm: 2.3.3
25+
gemfile: gemfiles/6.0.gemfile
1826
- rvm: 2.4.1
1927
gemfile: gemfiles/3.2.gemfile
2028
- rvm: 2.4.1
@@ -23,7 +31,23 @@ matrix:
2331
gemfile: gemfiles/4.1.gemfile
2432
- rvm: 2.4.1
2533
gemfile: gemfiles/4.2.gemfile
34+
- rvm: 2.4.1
35+
gemfile: gemfiles/6.0.gemfile
36+
- rvm: 2.5.1
37+
gemfile: gemfiles/3.2.gemfile
38+
- rvm: 2.5.1
39+
gemfile: gemfiles/4.0.gemfile
40+
- rvm: 2.5.1
41+
gemfile: gemfiles/4.1.gemfile
42+
- rvm: 2.5.1
43+
gemfile: gemfiles/4.2.gemfile
44+
- rvm: 2.6.0
45+
gemfile: gemfiles/4.0.gemfile
46+
- rvm: 2.6.0
47+
gemfile: gemfiles/4.1.gemfile
48+
- rvm: 2.6.0
49+
gemfile: gemfiles/4.2.gemfile
2650
# We need to install latest version of bundler, because one in travis
2751
# image is too old to recognize platform => :mri_22 in Gemfile.
2852
before_install:
29-
- gem install bundler
53+
- gem install bundler || gem install bundler -v 1.17.3

CHANGELOG.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,81 @@
22

33
## Unreleased
44

5+
## 1.16.1
6+
7+
- [#361](https://github.com/JsonApiClient/json_api_client/pull/361) - Call super from inherited method so that it will execute parent classes' implementations
8+
9+
## 1.16.0
10+
11+
- [#359](https://github.com/JsonApiClient/json_api_client/pull/359) - Support gzip content encoding
12+
13+
## 1.15.0
14+
15+
- [#346](https://github.com/JsonApiClient/json_api_client/pull/346) - add the option to have immutable resources
16+
- [#357](https://github.com/JsonApiClient/json_api_client/pull/357) - fix missing constant formatter
17+
18+
## 1.14.1
19+
20+
- [#353](https://github.com/JsonApiClient/json_api_client/pull/353) - fix to support deserializing resources with relationships without those related resources being included in the response (issue [#352](https://github.com/JsonApiClient/json_api_client/issues/352)).
21+
22+
## 1.14.0
23+
24+
- [#338](https://github.com/JsonApiClient/json_api_client/pull/338) - implement hash and eql? for builder class
25+
- [#351](https://github.com/JsonApiClient/json_api_client/pull/351) - Remove rudimental `last_result_set` relationship from serializer
26+
27+
## 1.13.0
28+
29+
- [#348](https://github.com/JsonApiClient/json_api_client/pull/348) - add NestedParamPaginator to address inconsistency in handling of pagination query string params (issue [#347](https://github.com/JsonApiClient/json_api_client/issues/347)).
30+
31+
## 1.12.2
32+
33+
- [#350](https://github.com/JsonApiClient/json_api_client/pull/350) - fix resource including with blank `relationships` response data
34+
35+
## 1.12.1
36+
37+
- [#349](https://github.com/JsonApiClient/json_api_client/pull/349) - fix resource including for STI objects
38+
39+
## 1.12.0
40+
41+
- [#345](https://github.com/JsonApiClient/json_api_client/pull/345) - track the real HTTP reason of ApiErrors
42+
43+
## 1.11.0
44+
45+
- [#344](https://github.com/JsonApiClient/json_api_client/pull/344) - introduce safe singular resource fetching with `raise_on_blank_find_param` resource setting
46+
47+
## 1.10.0
48+
49+
- [#335](https://github.com/JsonApiClient/json_api_client/pull/335) - access to assigned relationship
50+
51+
## 1.9.0
52+
53+
- [#328](https://github.com/JsonApiClient/json_api_client/pull/328) - allow custom type for models
54+
55+
- [#326](https://github.com/JsonApiClient/json_api_client/pull/326) - correct changes after initialize resource
56+
* remove type from changes on initialize
57+
* ensure that query builder doesn't propagate query values to resource attributes via #build method
58+
59+
- [#324](https://github.com/JsonApiClient/json_api_client/pull/324) - add possibility to override status handling
60+
* add status_handlers to JsonApiClient::Resource.connection_options
61+
62+
- [#330](https://github.com/JsonApiClient/json_api_client/pull/330) - deletion use overridden primary key
63+
64+
## 1.8.0
65+
66+
- [#316](https://github.com/JsonApiClient/json_api_client/pull/316) - Allow custom error messages
67+
68+
- [#305](https://github.com/JsonApiClient/json_api_client/pull/305) - optional search relationship data in result set
69+
70+
## 1.7.0
71+
72+
- [#320](https://github.com/JsonApiClient/json_api_client/pull/320) - fix passing relationships on create
73+
* fix relationships passing to `new` and `create` methods
74+
* fix false positive tests on create
75+
* refactor tests on create/update to prevent false same positive tests in future
76+
77+
- [#315](https://github.com/JsonApiClient/json_api_client/pull/315) - add shallow_path feature to belongs_to
78+
* add `shallow_path` options to belongs_to to use model w/ and w/o nesting in parent resource
79+
580
## v1.6.4
681
- [#314](https://github.com/JsonApiClient/json_api_client/pull/314) - Mimic ActiveRecord behavior when destroying a resource:
782
* Add `destroyed?` method

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ gem 'addressable', '~> 2.2'
1111
gem "codeclimate-test-reporter", group: :test, require: nil
1212

1313
group :development, :test do
14-
gem 'byebug', platforms: [:mri_20, :mri_21, :mri_22]
14+
gem 'byebug', '~> 10.0', platforms: [:mri_20, :mri_21, :mri_22]
1515
end

README.md

Lines changed: 141 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This gem is meant to help you build an API client for interacting with REST APIs as laid out by [http://jsonapi.org](http://jsonapi.org). It attempts to give you a query building framework that is easy to understand (it is similar to ActiveRecord scopes).
44

5-
*Note: master is currently tracking the 1.0.0 specification. If you're looking for the older code, see [0.x branch](https://github.com/chingor13/json_api_client/tree/0.x)*
5+
*Note: master is currently tracking the 1.0.0 specification. If you're looking for the older code, see [0.x branch](https://github.com/JsonApiClient/json_api_client/tree/0.x)*
66

77
## Usage
88

@@ -52,14 +52,14 @@ u.update_attributes(
5252
c: "d"
5353
)
5454

55-
u.persisted?
55+
u.persisted?
5656
# => true
5757

5858
u.destroy
5959

60-
u.destroyed?
60+
u.destroyed?
6161
# => true
62-
u.persisted?
62+
u.persisted?
6363
# => false
6464

6565
u = MyApi::Person.create(
@@ -157,13 +157,17 @@ articles.links.related
157157

158158
You can force nested resource paths for your models by using a `belongs_to` association.
159159

160-
**Note: Using belongs_to is only necessary for setting a nested path.**
160+
**Note: Using belongs_to is only necessary for setting a nested path unless you provide `shallow_path: true` option.**
161161

162162
```ruby
163163
module MyApi
164164
class Account < JsonApiClient::Resource
165165
belongs_to :user
166166
end
167+
168+
class Customer < JsonApiClient::Resource
169+
belongs_to :user, shallow_path: true
170+
end
167171
end
168172

169173
# try to find without the nested parameter
@@ -173,6 +177,28 @@ MyApi::Account.find(1)
173177
# makes request to /users/2/accounts/1
174178
MyApi::Account.where(user_id: 2).find(1)
175179
# => returns ResultSet
180+
181+
# makes request to /customers/1
182+
MyApi::Customer.find(1)
183+
# => returns ResultSet
184+
185+
# makes request to /users/2/customers/1
186+
MyApi::Customer.where(user_id: 2).find(1)
187+
# => returns ResultSet
188+
```
189+
190+
you can also override param name for `belongs_to` association
191+
192+
```ruby
193+
module MyApi
194+
class Account < JsonApiClient::Resource
195+
belongs_to :user, param: :customer_id
196+
end
197+
end
198+
199+
# makes request to /users/2/accounts/1
200+
MyApi::Account.where(customer_id: 2).find(1)
201+
# => returns ResultSet
176202
```
177203

178204
## Custom Methods
@@ -448,6 +474,52 @@ module MyApi
448474
end
449475
```
450476
477+
##### Server errors handling
478+
479+
Non-success API response will cause the specific `JsonApiClient::Errors::SomeException` raised, depends on responded HTTP status.
480+
Please refer to [JsonApiClient::Middleware::Status#handle_status](https://github.com/JsonApiClient/json_api_client/blob/master/lib/json_api_client/middleware/status.rb)
481+
method for concrete status-to-exception mapping used out of the box.
482+
483+
JsonApiClient will try determine is failed API response JsonApi-compatible, if so - JsonApi error messages will be parsed from response body, and tracked as a part of particular exception message. In additional, `JsonApiClient::Errors::ServerError` exception will keep the actual HTTP status and message within its message.
484+
485+
##### Custom status handler
486+
487+
You can change handling of response status using `connection_options`. For example you can override 400 status handling.
488+
By default it raises `JsonApiClient::Errors::ClientError` but you can skip exception if you want to process errors from the server.
489+
You need to provide a `proc` which should call `throw(:handled)` default handler for this status should be skipped.
490+
```ruby
491+
class ApiBadRequestHandler
492+
def self.call(_env)
493+
# do not raise exception
494+
end
495+
end
496+
497+
class CustomUnauthorizedError < StandardError
498+
attr_reader :env
499+
500+
def initialize(env)
501+
@env = env
502+
super('not authorized')
503+
end
504+
end
505+
506+
MyApi::Base.connection_options[:status_handlers] = {
507+
400 => ApiBadRequestHandler,
508+
401 => ->(env) { raise CustomUnauthorizedError, env }
509+
}
510+
511+
module MyApi
512+
class User < Base
513+
# will use the customized status_handlers
514+
end
515+
end
516+
517+
user = MyApi::User.create(name: 'foo')
518+
# server responds with { errors: [ { detail: 'bad request' } ] }
519+
user.errors.messages # { base: ['bad request'] }
520+
# on 401 it will raise CustomUnauthorizedError instead of JsonApiClient::Errors::NotAuthorized
521+
```
522+
451523
##### Specifying an HTTP Proxy
452524

453525
All resources have a class method ```connection_options``` used to pass options to the JsonApiClient::Connection initializer.
@@ -505,7 +577,7 @@ end
505577
506578
You can customize how your resources find pagination information from the response.
507579
508-
If the [existing paginator](https://github.com/chingor13/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) fits your requirements but you don't use the default `page` and `per_page` params for pagination, you can customise the param keys as follows:
580+
If the [existing paginator](https://github.com/JsonApiClient/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) fits your requirements but you don't use the default `page` and `per_page` params for pagination, you can customise the param keys as follows:
509581
510582
```ruby
511583
JsonApiClient::Paginating::Paginator.page_param = "number"
@@ -514,7 +586,7 @@ JsonApiClient::Paginating::Paginator.per_page_param = "size"
514586
515587
Please note that this is a global configuration, so library authors should create a custom paginator that inherits `JsonApiClient::Paginating::Paginator` and configure the custom paginator to avoid modifying global config.
516588
517-
If the [existing paginator](https://github.com/chingor13/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) does not fit your needs, you can create a custom paginator:
589+
If the [existing paginator](https://github.com/JsonApiClient/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) does not fit your needs, you can create a custom paginator:
518590
519591
```ruby
520592
class MyPaginator
@@ -527,6 +599,36 @@ class MyApi::Base < JsonApiClient::Resource
527599
end
528600
```
529601
602+
### NestedParamPaginator
603+
604+
The default `JsonApiClient::Paginating::Paginator` is not strict about how it handles the param keys ([#347](https://github.com/JsonApiClient/json_api_client/issues/347)). There is a second paginator that more rigorously adheres to the JSON:API pagination recommendation style of `page[page]=1&page[per_page]=10`.
605+
606+
If this second style suits your needs better, it is available as a class override:
607+
608+
```ruby
609+
class Order < JsonApiClient::Resource
610+
self.paginator = JsonApiClient::Paginating::NestedParamPaginator
611+
end
612+
```
613+
614+
You can also extend `NestedParamPaginator` in your custom paginators or assign the `page_param` or `per_page_param` as with the default version above.
615+
616+
### Custom type
617+
618+
If your model must be named differently from classified type of resource you can easily customize it.
619+
It will work both for defined and not defined relationships
620+
621+
```ruby
622+
class MyApi::Base < JsonApiClient::Resource
623+
resolve_custom_type 'document--files', 'File'
624+
end
625+
626+
class MyApi::File < MyApi::Base
627+
def self.resource_name
628+
'document--files'
629+
end
630+
end
631+
```
530632
531633
### Type Casting
532634
@@ -556,6 +658,37 @@ end
556658

557659
```
558660
661+
### Safe singular resource fetching
662+
663+
That is a bit curios, but `json_api_client` returns an array from `.find` method, always.
664+
The history of this fact was discussed [here](https://github.com/JsonApiClient/json_api_client/issues/75)
665+
666+
So, when we searching for a single resource by primary key, we typically write the things like
667+
668+
```ruby
669+
admin = User.find(id).first
670+
```
671+
672+
The next thing which we need to notice - `json_api_client` will just interpolate the incoming `.find` param to the end of API URL, just like that:
673+
674+
> http://somehost/api/v1/users/{id}
675+
676+
What will happen if we pass the blank id (nil or empty string) to the `.find` method then?.. Yeah, `json_api_client` will try to call the INDEX API endpoint instead of SHOW one:
677+
678+
> http://somehost/api/v1/users/
679+
680+
Lets sum all together - in case if `id` comes blank (from CGI for instance), we can silently receive the `admin` variable equal to some existing resource, with all the consequences.
681+
682+
Even worse, `admin` variable can equal to *random* resource, depends on ordering applied by INDEX endpoint.
683+
684+
If you prefer to get `JsonApiClient::Errors::NotFound` raised, please define in your base Resource class:
685+
686+
```ruby
687+
class Resource < JsonApiClient::Resource
688+
self.raise_on_blank_find_param = true
689+
end
690+
```
691+
559692
## Contributing
560693
561694
Contributions are welcome! Please fork this repo and send a pull request. Your pull request should have:
@@ -569,4 +702,4 @@ required. The commits will be squashed into master once accepted.
569702
570703
## Changelog
571704
572-
See [changelog](https://github.com/chingor13/json_api_client/blob/master/CHANGELOG.md)
705+
See [changelog](https://github.com/JsonApiClient/json_api_client/blob/master/CHANGELOG.md)

gemfiles/5.2.3.gemfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# This file was generated by Appraisal
2+
3+
source "https://rubygems.org"
4+
5+
gem "rake"
6+
gem "appraisal"
7+
gem "activesupport", "~> 5.2.3"
8+
gem "addressable", "~> 2.2"
9+
gem "codeclimate-test-reporter", :group => :test, :require => nil
10+
11+
group :development, :test do
12+
gem "byebug", :platforms => [:mri_20, :mri_21, :mri_22]
13+
end
14+
15+
gemspec :path => "../"

0 commit comments

Comments
 (0)