Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* [#319](https://github.com/codegram/hyperclient/pull/319): Fixed `Resource#to_h` returning `nil` instead of the same result as `#to_hash` - [@dblock](https://github.com/dblock).
* [#320](https://github.com/codegram/hyperclient/pull/320): Documented how to handle non-`hal+json` responses via the Faraday response middleware's `content_type` matcher - [@dblock](https://github.com/dblock).
* [#321](https://github.com/codegram/hyperclient/pull/321): Added Ruby 4.0 to the CI test matrix - [@dblock](https://github.com/dblock).
* [#322](https://github.com/codegram/hyperclient/pull/322): Fixed `Link` caching a mutating request's (`_post`/`_put`/`_patch`/`_delete`) response as its resource, causing subsequent reads (e.g. `#each`, `method_missing`) to return stale data instead of a fresh `_get` - [@dblock](https://github.com/dblock).
* Your contribution here.

### 2.0.0 (2024/02/01)
Expand Down
17 changes: 13 additions & 4 deletions lib/hyperclient/link.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,19 @@ def _uri_template
end

def http_method(method, body = nil)
@resource = begin
response = @entry_point.connection.run_request(method, _url, body, nil)
Resource.new(response.body, @entry_point, response)
end
response = @entry_point.connection.run_request(method, _url, body, nil)
resource = Resource.new(response.body, @entry_point, response)

# Only cache GET responses. Caching the response of a mutating
# request (POST/PUT/PATCH/DELETE) as `@resource` would make
# subsequent delegated calls (e.g. `#each`, `method_missing`) see
# the stale mutation response instead of fetching a fresh
# resource, requiring users to create a new client between a
# `_post` and a `_get`. See #107.
@resource = resource if method == :get
@delegate = nil

resource
end
end
end
13 changes: 13 additions & 0 deletions test/hyperclient/link_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ module Hyperclient

link._resource
end

it 'fetches a fresh resource after a mutating request instead of returning the cached response (#107)' do
link = Link.new('key', { 'href' => '/productions/1' }, entry_point)

stub_request(entry_point.connection) do |stub|
stub.post('http://api.example.org/productions/1') { [201, {}, { 'status' => 'created' }] }
stub.get('http://api.example.org/productions/1') { [200, {}, { 'status' => 'fetched' }] }
end

link._post('foo' => 'bar')

_(link._resource.status).must_equal 'fetched'
end
end

describe 'get' do
Expand Down
Loading