Current section
Files
Jump to
Current section
Files
lib/merca_ex.ex
defmodule MercaEx do
@moduledoc """
Elixir client for the Mercadona API.
MercaEx provides a simple interface to interact with Mercadona's
product catalog, including browsing categories, fetching products,
and searching.
## Usage
# List all categories
{:ok, categories} = MercaEx.categories()
# Get products in a category
{:ok, products} = MercaEx.products(category_id)
# Get a specific product
{:ok, product} = MercaEx.product("1234")
# Search for products
{:ok, results} = MercaEx.search("leche")
## Configuration
The HTTP client can be configured for testing:
config :merca_ex, :http_client, MercaEx.HTTPClientMock
"""
alias MercaEx.{Algolia, Category, Client, Product}
@doc """
Fetches all product categories.
Returns a list of top-level categories, each containing
their subcategories.
## Examples
iex> {:ok, categories} = MercaEx.categories()
iex> hd(categories).name
"Aceite, especias y salsas"
"""
@spec categories() :: {:ok, [Category.t()]} | {:error, term()}
def categories do
case Client.get("/categories/") do
{:ok, %{"results" => results}} ->
categories = Enum.map(results, &Category.from_api/1)
{:ok, categories}
{:error, _} = error ->
error
end
end
@doc """
Fetches products for a specific category.
## Parameters
- `category_id` - The category ID (integer or string)
## Examples
iex> {:ok, products} = MercaEx.products(113)
iex> hd(products).name
"Aceite de oliva virgen extra"
"""
@spec products(integer() | String.t()) :: {:ok, [Product.t()]} | {:error, term()}
def products(category_id) do
path = "/categories/#{category_id}/"
case Client.get(path) do
{:ok, %{"categories" => categories}} ->
products =
categories
|> Enum.flat_map(fn cat -> cat["products"] || [] end)
|> Enum.map(&Product.from_api/1)
{:ok, products}
{:error, _} = error ->
error
end
end
@doc """
Fetches a single product by ID.
## Parameters
- `product_id` - The product ID (string)
## Examples
iex> {:ok, product} = MercaEx.product("1234")
iex> product.name
"Aceite de oliva virgen extra"
"""
@spec product(String.t()) :: {:ok, Product.t()} | {:error, term()}
def product(product_id) do
path = "/products/#{product_id}/"
case Client.get(path) do
{:ok, data} ->
{:ok, Product.from_api(data)}
{:error, _} = error ->
error
end
end
@doc """
Searches for products by query using Algolia.
## Parameters
- `query` - Search term
- `opts` - Optional parameters:
- `:warehouse` - Warehouse code (default: "mad1"). See `MercaEx.Algolia.available_warehouses/0`
- `:limit` - Maximum results to return (default: 20)
## Examples
iex> {:ok, products} = MercaEx.search("leche")
iex> length(products) > 0
true
iex> {:ok, products} = MercaEx.search("leche", warehouse: "bcn1", limit: 5)
"""
@spec search(String.t(), keyword()) :: {:ok, [Product.t()]} | {:error, term()}
def search(query, opts \\ []) do
Algolia.search(query, opts)
end
end