Files
wanderer/lib/wanderer_app_web/api_router_helpers.ex
2025-07-16 23:17:47 +00:00

115 lines
2.8 KiB
Elixir

defmodule WandererAppWeb.ApiRouterHelpers do
@moduledoc """
Helper functions for version-aware API routing.
"""
alias WandererAppWeb.Plugs.ApiVersioning
def version_specific_action(base_action, version) do
# Validate version format before converting to atom
validated_version =
case validate_version_format(version) do
:ok -> String.replace(version, ".", "_")
# fallback to v1
:error -> "1"
end
String.to_atom("#{base_action}_v#{validated_version}")
end
def supports_feature?(conn, feature) do
version = conn.assigns[:api_version]
ApiVersioning.version_supports_feature?(version, feature)
end
def get_pagination_params(conn) do
version_config = conn.assigns[:version_config]
case conn.assigns[:api_version] do
"1.0" ->
# Legacy pagination
%{
page: parse_integer(conn.params["page"], 1),
per_page:
min(
parse_integer(conn.params["per_page"], version_config.default_page_size),
version_config.max_page_size
)
}
_ ->
# JSON:API pagination
page_params = conn.params["page"] || %{}
%{
number: parse_integer(page_params["number"], 1),
size:
min(
parse_integer(page_params["size"], version_config.default_page_size),
version_config.max_page_size
)
}
end
end
def get_filter_params(conn) do
if supports_feature?(conn, :filtering) do
conn.params["filter"] || %{}
else
%{}
end
end
def get_sort_params(conn) do
if supports_feature?(conn, :sorting) do
conn.params["sort"]
else
nil
end
end
def get_include_params(conn) do
if supports_feature?(conn, :includes) do
case conn.params["include"] do
include when is_binary(include) -> String.split(include, ",")
include when is_list(include) -> include
_ -> []
end
else
[]
end
end
def get_sparse_fields_params(conn) do
if supports_feature?(conn, :sparse_fieldsets) do
conn.params["fields"] || %{}
else
%{}
end
end
# Private helper functions
# Safe integer parsing helper
defp parse_integer(value, default) when is_binary(value) do
case Integer.parse(value) do
{int, ""} -> int
_ -> default
end
end
defp parse_integer(value, _default) when is_integer(value), do: value
defp parse_integer(_value, default), do: default
# Validate version format (digits separated by dots or just digits)
defp validate_version_format(version) when is_binary(version) do
if Regex.match?(~r/^\d+(\.\d+)*$/, version) do
:ok
else
:error
end
end
defp validate_version_format(_), do: :error
end