Skip to content

Instantly share code, notes, and snippets.

@nathan-cruz77
Created June 7, 2020 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathan-cruz77/8d51c556bfbd4e571a7aa93f8171a63c to your computer and use it in GitHub Desktop.
Save nathan-cruz77/8d51c556bfbd4e571a7aa93f8171a63c to your computer and use it in GitHub Desktop.
Parse query params and extract UUIDs from URIs
defmodule URIParser do
@doc """
Extracts path, query params and UUIDs from the given URI and return them as a map.
## Examples
iex> URIParser.parse("https://example.com/resource/3776a9b5-5f69-4d9e-be5e-74e574df02d6?page[number]=5&page[size]=3")
%{
path: "/resource/:id",
query: %{"page[number]" => "5", "page[size]" => "3"},
uuids: ["3776a9b5-5f69-4d9e-be5e-74e574df02d6"]
}
iex> URIParser.parse("https://example.com/resource/3776a9b5-5f69-4d9e-be5e-74e574df02d6/some_action/03e9cc08-3739-452b-8c4b-a9d4cfc55549?sort=some_field")
%{
path: "/resource/:id/some_action/:id",
query: %{"sort" => "some_field"},
uuids: ["3776a9b5-5f69-4d9e-be5e-74e574df02d6",
"03e9cc08-3739-452b-8c4b-a9d4cfc55549"]
}
iex> URIParser.parse("https://example.com/resource?sort=some_field")
%{
path: "/resource",
query: %{"sort" => "some_field"},
uuids: []
}
iex(79)> URIParser.parse("https://example.com/resource")
%{
path: "/resource",
query: %{},
uuids: []
}
"""
@uuid_regex ~r/([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})+/
def parse(uri) do
uri = URI.parse(uri)
%{path: path, uuids: uuid} = parse_uuid(uri.path)
%{
path: path,
uuids: uuid,
query: decode_query(uri.query)
}
end
defp parse_uuid(path) do
uuids =
@uuid_regex
|> Regex.scan(path, capture: :first)
|> List.flatten()
%{
uuids: uuids,
path: Regex.replace(@uuid_regex, path, ":id")
}
end
defp decode_query(query_string) when is_binary(query_string) do
URI.decode_query(query_string)
end
defp decode_query(_) do
URI.decode_query("")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment