I have a module where am using GenServer
. In this module the state is a list of items. The module exposes functions to filter these items according to various criteria.
My question is what is the best approach to solving this task. Would it be better to:
- Add multiple
handle_call
callbacks for each filter criterion. - Use the
list_items
functions and then filter its return value using multiple helper functions instead of the multiplehandle_call
callbacks.
Here is a simple implementation of the first approach:
defmodule Repositories do
use GenServer
## API
def start_link(_opts) do
.GenServer.start_link(__MODULE__, :ok)
end
def list_items(pid) do
GenServer.call(pid, :list_items)
end
def filter_by_name(pid, repo_name) do
GenServer.call(pid, {:filter_by_name, repo_name})
end
# Other APIs here for filtering by other criteria
....
## Server
def init(:ok) do
initial_repos = #Fetch initial repos.
{:ok, initial_repos}
end
def handle_call({:filter_by_name, repo_name}, _from, state) do
matching_repos = Enum.filter(state, fn repo -> String.equivalent?(repo.name, repo_name) end)
{:reply, matching_repos, state}
end
def handle_call(:list_items, _from, state) do
{:reply, state, state}
end
# Other callbacks here for handling calls to filter by the other various criteria
....
end
Here is a simple implementation of the second approach:
defmodule Repositories do
use GenServer
## API
def start_link(_opts) do
.GenServer.start_link(__MODULE__, :ok)
end
def list_items(pid) do
GenServer.call(pid, :list_items)
end
def filter_by_name(pid, repo_name) do
pid
|> list_items()
|> Enum.filter(fn repo -> has_name?(repo.name, repo_name) end)
end
# Other APIs here for filtering by other criteria
....
## Server
def init(:ok) do
initial_repos = #Fetch initial repos.
{:ok, initial_repos}
end
def handle_call(:list_items, _from, state) do
{:reply, state, state}
end
## Helper functions
def has_name?(actual_name, repo_name) do
String.equivalent?(actual_name, repo_name)
end
# Other helper functions to perform filtering by other criteria
....
end
Which approach is more favored in the elixir community?