{"id":13531537,"url":"https://github.com/sourcelevel/faraday-http-cache","last_synced_at":"2025-04-05T03:09:09.191Z","repository":{"id":2410790,"uuid":"3378613","full_name":"sourcelevel/faraday-http-cache","owner":"sourcelevel","description":"A Faraday middleware that respects HTTP cache","archived":false,"fork":false,"pushed_at":"2024-01-16T12:39:05.000Z","size":477,"stargazers_count":342,"open_issues_count":6,"forks_count":86,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-02-04T12:04:14.721Z","etag":null,"topics":["cache","faraday","http","middleware","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sourcelevel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-02-07T15:39:38.000Z","updated_at":"2024-12-17T08:07:46.000Z","dependencies_parsed_at":"2024-06-18T11:21:27.146Z","dependency_job_id":"68059c7f-4f2c-415c-b19a-5d8e640a98d3","html_url":"https://github.com/sourcelevel/faraday-http-cache","commit_stats":{"total_commits":369,"total_committers":41,"mean_commits":9.0,"dds":0.3739837398373984,"last_synced_commit":"3f1bf705c9b6050cf48d382b33bc0ee402012ccd"},"previous_names":["plataformatec/faraday-http-cache"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcelevel%2Ffaraday-http-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcelevel%2Ffaraday-http-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcelevel%2Ffaraday-http-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcelevel%2Ffaraday-http-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sourcelevel","download_url":"https://codeload.github.com/sourcelevel/faraday-http-cache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238337943,"owners_count":19455402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","faraday","http","middleware","ruby"],"created_at":"2024-08-01T07:01:03.810Z","updated_at":"2025-03-14T01:17:04.201Z","avatar_url":"https://github.com/sourcelevel.png","language":"Ruby","readme":"# Faraday Http Cache\n\n[![Gem Version](https://badge.fury.io/rb/faraday-http-cache.svg)](https://rubygems.org/gems/faraday-http-cache)\n[![Build](https://github.com/sourcelevel/faraday-http-cache/actions/workflows/main.yml/badge.svg)](https://github.com/sourcelevel/faraday-http-cache/actions)\n\nA [Faraday](https://github.com/lostisland/faraday) middleware that respects HTTP cache,\nby checking expiration and validation of the stored responses.\n\n## Installation\n\nAdd it to your Gemfile:\n\n```ruby\ngem 'faraday-http-cache'\n```\n\n## Usage and configuration\n\nYou have to use the middleware in the Faraday instance that you want to,\nalong with a suitable `store` to cache the responses. You can use the new\nshortcut using a symbol or passing the middleware class\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache\n  # or\n  builder.use Faraday::HttpCache, store: Rails.cache\n\n  builder.adapter Faraday.default_adapter\nend\n```\n\nThe middleware accepts a `store` option for the cache backend responsible for recording\nthe API responses that should be stored. Stores should respond to `write`, `read` and `delete`,\njust like an object from the `ActiveSupport::Cache` API.\n\n```ruby\n# Connect the middleware to a Memcache instance.\nstore = ActiveSupport::Cache.lookup_store(:mem_cache_store, ['localhost:11211'])\n\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: store\n  builder.adapter Faraday.default_adapter\nend\n\n# Or use the Rails.cache instance inside your Rails app.\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache\n  builder.adapter Faraday.default_adapter\nend\n```\nThe default store provided is a simple in memory cache that lives on the client instance.\nThis type of store **might not be persisted across multiple processes or connection instances**\nso it is probably not suitable for most production environments.\nMake sure that you configure a store that is suitable for you.\n\nThe stdlib `JSON` module is used for serialization by default, which can struggle with unicode\ncharacters in responses in Ruby \u003c 3.1. For example, if your JSON returns `\"name\": \"Raül\"` then\nyou might see errors like:\n\n```\nResponse could not be serialized: \"\\xC3\" from ASCII-8BIT to UTF-8. Try using Marshal to serialize.\n```\n\nFor full unicode support, or if you expect to be dealing with images, you can use the stdlib\n[Marshal][marshal] instead. Alternatively you could use another json library like `oj` or `yajl-ruby`.\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache, serializer: Marshal\n  builder.adapter Faraday.default_adapter\nend\n```\n\n### Strategies\n\nYou can provide a `:strategy` option to the middleware to specify the strategy to use.\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache, strategy: Faraday::HttpCache::Strategies::ByVary\n  builder.adapter Faraday.default_adapter\nend\n```\n\nAvailable strategies are:\n\n#### `Faraday::HttpCache::Strategies::ByUrl`\n\nThe default strategy.\nIt Uses URL + HTTP method to generate cache keys and stores an array of request + response for each key.\n\n#### `Faraday::HttpCache::Strategies::ByVary`\n\nThis strategy uses headers from `Vary` header to generate cache keys.\nIt also uses cache to store `Vary` headers mapped to the request URL.\nThis strategy is more suitable for caching private responses with the same URLs but different results for different users, like `https://api.github.com/user`.\n\n*Note:* To automatically remove stale cache keys, you might want to use the `:expires_in` option.\n\n```ruby\nstore = ActiveSupport::Cache.lookup_store(:redis_cache_store, expires_in: 1.day, url: 'redis://localhost:6379/0')\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: store, strategy: Faraday::HttpCache::Strategies::ByVary\n  builder.adapter Faraday.default_adapter\nend\n```\n\n#### Custom strategies\n\nYou can write your own strategy by subclassing `Faraday::HttpCache::Strategies::BaseStrategy` and implementing `#write`, `#read` and `#delete` methods.\n\n### Logging\n\nYou can provide a `:logger` option that will receive debug information based on the middleware\noperations:\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache, logger: Rails.logger\n  builder.adapter Faraday.default_adapter\nend\n\nclient.get('https://site/api/users')\n# logs \"HTTP Cache: [GET users] miss, store\"\n```\n\n### Instrumentation\n\nIn addition to logging you can instrument the middleware by passing in an `:instrumenter` option\nsuch as ActiveSupport::Notifications (compatible objects are also allowed).\n\nThe event `http_cache.faraday` will be published every time the middleware\nprocesses a request. In the event payload, `:env` contains the response Faraday env and\n`:cache_status` contains a Symbol indicating the status of the cache processing for that request:\n\n- `:unacceptable` means that the request did not go through the cache at all.\n- `:miss` means that no cached response could be found.\n- `:invalid` means that the cached response could not be validated against the server.\n- `:valid` means that the cached response *could* be validated against the server.\n- `:fresh` means that the cached response was still fresh and could be returned without even\n  calling the server.\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, store: Rails.cache, instrumenter: ActiveSupport::Notifications\n  builder.adapter Faraday.default_adapter\nend\n\n# Subscribes to all events from Faraday::HttpCache.\nActiveSupport::Notifications.subscribe \"http_cache.faraday\" do |*args|\n  event = ActiveSupport::Notifications::Event.new(*args)\n  cache_status = event.payload[:cache_status]\n  statsd = Statsd.new\n\n  case cache_status\n  when :fresh, :valid\n    statsd.increment('api-calls.cache_hits')\n  when :invalid, :miss\n    statsd.increment('api-calls.cache_misses')\n  when :unacceptable\n    statsd.increment('api-calls.cache_bypass')\n  end\nend\n```\n\n## See it live\n\nYou can clone this repository, install its dependencies with Bundler (run `bundle install`) and\nexecute the files under the `examples` directory to see a sample of the middleware usage.\n\n## What gets cached?\n\nThe middleware will use the following headers to make caching decisions:\n- Vary\n- Cache-Control\n- Age\n- Last-Modified\n- ETag\n- Expires\n\n### Cache-Control\n\nThe `max-age`, `must-revalidate`, `proxy-revalidate` and `s-maxage` directives are checked.\n\n### Shared vs. non-shared caches\n\nBy default, the middleware acts as a \"shared cache\" per RFC 2616. This means it does not cache\nresponses with `Cache-Control: private`. This behavior can be changed by passing in the\n`:shared_cache` configuration option:\n\n```ruby\nclient = Faraday.new do |builder|\n  builder.use :http_cache, shared_cache: false\n  builder.adapter Faraday.default_adapter\nend\n\nclient.get('https://site/api/some-private-resource') # =\u003e will be cached\n```\n\n## License\n\nCopyright (c) 2012-2018 Plataformatec.\nCopyright (c) 2019 SourceLevel and contributors.\n\n  [marshal]: https://www.ruby-doc.org/core-3.0/Marshal.html\n","funding_links":[],"categories":["Middleware","Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcelevel%2Ffaraday-http-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsourcelevel%2Ffaraday-http-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcelevel%2Ffaraday-http-cache/lists"}