README.md

# MaxwellCache
[![Build Status](https://travis-ci.org/milkwine/maxwell_cache.svg?branch=master)](https://travis-ci.org/milkwine/maxwell_cache)

Maxwell middleware to cache success response. Backend by [Cachex](https://github.com/whitfin/cachex).

## Installation

Add `maxwell_cache` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:maxwell_cache, ~> 0.1.0"},
  ]
end
```

## Usage

More `Maxwell` usage could be seen [here](https://github.com/zhongwencool/maxwell).

Short usage of this middleware here:
```elixir

    #Set Maxwell Middleware.
    middleware Maxwell.Middleware.Cache, ttl: :timer.minutes(1), namespace: "httpbin"


    # Import middleware method.
    import Maxwell.Middleware.Cache, only: [from_cache: 1, from_source: 1, set_ttl: 2]

    # Middleware is doing nothing.
    def get_uuid do
      "/uuid"
      |> new()
      |> get!
      |> get_resp_body
    end

    # Set to requrest from real remote server and set cache if response success.
    def get_uuid_from_source do
      "/uuid"
      |> new()
      |> from_source()
      |> get!
      |> get_resp_body
    end

    # Set to get response from cache first and set ttl. Request real remote server if cache not found.
    def get_uuid_from_cache do
      "/uuid"
      |> new()
      |> from_cache()
      |> set_ttl(:timer.seconds(5))
      |> get!
      |> get_resp_body
    end
```

## Options

### Cache key relate to request
Cache key is consist of two parts, middleware `namespace` and information generated by `hash_func/1`.

Default `hash_func/1` is below:
```elixir
  def default_hash_func(%Maxwell.Conn{} = conn) do
    query_string = conn.query_string |> Maxwell.Query.encode
    headers      = conn.req_headers  |> Maxwell.Query.encode
    body         = conn.req_body     |> :erlang.phash2

    "#{conn.method}|#{conn.url}|#{conn.path}|#{query_string}|#{headers}|#{body}"
  end
```

Both of them could be set by middleware `init/1`.

```elixir
    middleware Maxwell.Middleware.Cache, namespace: "yournamespace", hash_func: &your_hash_func/1
```

### Cache limit

Default `Cachex limit` is `%Cachex.Limit{limit: 2000, reclaim: 0.1}`, could be change in `config.exs`:

```elixir
config :maxwell_cache, limit: %Cachex.Limit{limit: 2000, reclaim: 0.1}
```

More information could be seen [cachex doc](https://hexdocs.pm/cachex/readme.html#cache-limits).

### Cache ttl

Default ttl is `:timer.seconds(10)`, this could be change in `config.exs`:

```elixir
config :maxwell_cache, default_ttl: :timer.seconds(10)
```

Client moudle could have their own ttl:
```elixir
    middleware Maxwell.Middleware.Cache, ttl: :timer.seconds(10)
```

Request could set ttl by using `set_ttl/1`:
```elixir
    def get_uuid_from_cache do
      "/uuid"
      |> new()
      |> from_cache()
      |> set_ttl(:timer.seconds(5))
      |> get!
      |> get_resp_body
    end
```