{"id":17306465,"url":"https://github.com/jhthorsen/mojo-useragent-role-cache","last_synced_at":"2025-10-18T20:48:32.315Z","repository":{"id":56840255,"uuid":"150215679","full_name":"jhthorsen/mojo-useragent-role-cache","owner":"jhthorsen","description":"Add caching to Mojo::UserAgent","archived":false,"fork":false,"pushed_at":"2019-04-05T05:37:57.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-18T05:17:10.060Z","etag":null,"topics":["mojolicious","perl","testing","web"],"latest_commit_sha":null,"homepage":"https://metacpan.org/pod/Mojo::UserAgent::Role::Cache","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jhthorsen.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-25T06:07:19.000Z","updated_at":"2019-04-05T05:37:54.000Z","dependencies_parsed_at":"2022-08-29T05:01:34.616Z","dependency_job_id":null,"html_url":"https://github.com/jhthorsen/mojo-useragent-role-cache","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhthorsen%2Fmojo-useragent-role-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhthorsen%2Fmojo-useragent-role-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhthorsen%2Fmojo-useragent-role-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhthorsen%2Fmojo-useragent-role-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhthorsen","download_url":"https://codeload.github.com/jhthorsen/mojo-useragent-role-cache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245755605,"owners_count":20667027,"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":["mojolicious","perl","testing","web"],"created_at":"2024-10-15T11:58:30.616Z","updated_at":"2025-10-18T20:48:27.277Z","avatar_url":"https://github.com/jhthorsen.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\nMojo::UserAgent::Role::Cache - Role for Mojo::UserAgent that provides caching\n\n# SYNOPSIS\n\n## General\n\n    # Apply the role\n    my $ua_class_with_cache = Mojo::UserAgent-\u003ewith_roles('+Cache');\n    my $ua = $ua_class_with_cache-\u003enew;\n\n    # Change the global cache driver\n    use CHI;\n    $ua_class_with_cache-\u003ecache_driver_singleton(CHI-\u003enew(driver =\u003e \"Memory\", datastore =\u003e {}));\n\n    # Or change the driver for the instance\n    $ua-\u003ecache_driver(CHI-\u003enew(driver =\u003e \"Memory\", datastore =\u003e {}));\n\n    # The rest is like a normal Mojo::UserAgent\n    my $tx = $ua-\u003eget($url)-\u003eerror;\n\n## Module\n\n    package MyCoolModule;\n    use Mojo::Base -base;\n\n    has ua =\u003e sub {\n      return $ENV{MOJO_USERAGENT_CACHE_STRATEGY}\n        ? Mojo::UserAgent-\u003ewith_roles('+Cache') : Mojo::UserAgent-\u003enew;\n    };\n\n    sub get_mojolicious_org {\n      return shift-\u003eua-\u003eget(\"https://mojolicious.org/\");\n    }\n\nUsing the `MOJO_USERAGENT_CACHE_STRATEGY` inside the module is a very\neffective way to either use the global cache set up by a unit test, or run with\nthe default [Mojo::UserAgent](https://metacpan.org/pod/Mojo::UserAgent) without caching.\n\n## Test\n\n    use Mojo::Base -strict;\n    use Mojo::UserAgent::Role::Cache;\n    use MyCoolModule;\n    use Test::More;\n\n    # Set up the environment and change the global cache_driver before running\n    # the tests\n    $ENV{MOJO_USERAGENT_CACHE_STRATEGY} ||= \"playback\";\n    Mojo::UserAgent::Role::Cache-\u003ecache_driver_singleton-\u003eroot_dir(\"/some/path\");\n\n    # Run the tests\n    my $cool = MyCoolModule-\u003enew;\n    is $cool-\u003eget_mojolicious_org-\u003eres-\u003ecode, 200, \"mojolicious.org works\";\n\n    done_testing;\n\n# DESCRIPTION\n\n[Mojo::UserAgent::Role::Cache](https://metacpan.org/pod/Mojo::UserAgent::Role::Cache) is a role for the full featured non-blocking\nI/O HTTP and WebSocket user agent [Mojo::UserAgent](https://metacpan.org/pod/Mojo::UserAgent), that provides caching.\n\nThe [\"SYNOPSIS\"](#synopsis) shows how to use this in with tests, but there's nothing wrong\nwith using it for other things as well, where you want caching.\n\nBy default, this module caches everything without any expiration. This is\nbecause [Mojo::UserAgent::Role::Cache::Driver::File](https://metacpan.org/pod/Mojo::UserAgent::Role::Cache::Driver::File) is very basic and\nactually just meant for unit testing. If you want something more complex, you\ncan use [CHI](https://metacpan.org/pod/CHI) or another [\"cache\\_driver\"](#cache_driver) that implements the logic you want.\n\nOne exotic hack that is possible, is to make [\"cache\\_key\"](#cache_key) return the whole\n[$tx](https://metacpan.org/pod/$tx) object and then implement a wrapper around [CHI](https://metacpan.org/pod/CHI) that will investigate\nthe transaction and see if it wants to cache the request at all.\n\n# WARNING\n\n## Experimenntal\n\n[Mojo::UserAgent::Role::Cache](https://metacpan.org/pod/Mojo::UserAgent::Role::Cache) is still under development, so there will be\nchanges and there is probably bugs that needs fixing. Please report in if you\nfind a bug or find this role interesting.\n\n[https://github.com/jhthorsen/mojo-useragent-role-cache/issues](https://github.com/jhthorsen/mojo-useragent-role-cache/issues)\n\n## Upgrading from 0.02 to 0.03\n\nUpgrading from version 0.02 to 0.03 will cause all your cached files to be\ninvalid, since the [\"cache\\_key\"](#cache_key) is changed. If you are using\n[Mojo::UserAgent::Role::Cache::Driver::File](https://metacpan.org/pod/Mojo::UserAgent::Role::Cache::Driver::File), you can set the environment\nvariable `MOJO_UA_CACHE_RENAME=1` to on-the-fly rename the old files to the\nnew format.\n\n# ATTRIBUTES\n\n## cache\\_driver\n\n    $obj = $self-\u003ecache_driver;\n    $self = $self-\u003ecache_driver(CHI-\u003enew);\n\nHolds an object that will get/set the HTTP messages. Default is\n[Mojo::UserAgent::Role::Cache::Driver::File](https://metacpan.org/pod/Mojo::UserAgent::Role::Cache::Driver::File), but any backend that supports\n`get()` and `set()` should do. This means that you can use [CHI](https://metacpan.org/pod/CHI) if you\nlike.\n\n## cache\\_key\n\n    $code = $self-\u003ecache_key;\n    $self = $self-\u003ecache_key(sub { my $tx = shift; return $tx-\u003ereq-\u003eurl });\n\nHolds a code ref that returns an array-ref of the key parts that is passed on\nto `get()` or `set()` in the [\"cache\\_driver\"](#cache_driver).\n\nThis works with [CHI](https://metacpan.org/pod/CHI) as well, since CHI will serialize the key if it is a\nreference.\n\nThe default is EXPERIMENTAL, but returns this value for now:\n\n    [\n      $http_method, # get, post, ...\n      $host,        # no port\n      $path_query,  # /foo?x=42\n      md5($body),   # but not for GET\n    ]\n\n## cache\\_strategy\n\n    $code = $self-\u003ecache_strategy;\n    $self = $self-\u003ecache_strategy(sub { my $tx = shift; return \"passthrough\" });\n\nUsed to set up a callback to return a cache strategy. Default value is read\nfrom the `MOJO_USERAGENT_CACHE_STRATEGY` environment variable or\n\"playback\\_or\\_record\".\n\nThe return value from the `$code` can be one of:\n\n- passthrough\n\n    Will disable any caching.\n\n- playback\n\n    Will never send a request to the remote server, but only look for recorded\n    messages.\n\n- playback\\_or\\_record\n\n    Will return a recorded message if it exists, or fetch one from the remote\n    server and store the response.\n\n- record\n\n    Will always fetch a new response from the remote server and store the response.\n\n# METHODS\n\n## cache\\_driver\\_singleton\n\n    $obj = Mojo::UserAgent::Role::Cache-\u003ecache_driver_singleton;\n    Mojo::UserAgent::Role::Cache-\u003ecache_driver_singleton($obj);\n\nUsed to retrieve or set the default [\"cache\\_driver\"](#cache_driver). Useful for setting up\ncaching globally in unit tests.\n\n# AUTHOR\n\nJan Henning Thorsen\n\n# COPYRIGHT AND LICENSE\n\nThis program is free software, you can redistribute it and/or modify it under\nthe terms of the Artistic License version 2.0.\n\n# SEE ALSO\n\n[Mojo::UserAgent](https://metacpan.org/pod/Mojo::UserAgent),\n[https://metacpan.org/pod/Mojo::UserAgent::Cached](https://metacpan.org/pod/Mojo::UserAgent::Cached) and\n[https://metacpan.org/pod/Mojo::UserAgent::Mockable](https://metacpan.org/pod/Mojo::UserAgent::Mockable).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhthorsen%2Fmojo-useragent-role-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhthorsen%2Fmojo-useragent-role-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhthorsen%2Fmojo-useragent-role-cache/lists"}