feat: Support Bundle conversion and Search endpoints
This commit is contained in:
parent
68cc47ba2e
commit
c7c6568e37
4 changed files with 53 additions and 13 deletions
|
@ -21,6 +21,25 @@ defmodule Kindling.Client do
|
|||
end
|
||||
end
|
||||
|
||||
def search(client, resource_module, params \\ [], opts \\ []) do
|
||||
base_uri = URI.parse(client.base_url)
|
||||
query = URI.encode_query(params)
|
||||
uri = base_uri |> URI.append_path(resource_module.path()) |> URI.append_query(query)
|
||||
more_headers = Keyword.get(opts, :headers, [])
|
||||
|
||||
headers = headers(client, more_headers)
|
||||
|
||||
uri
|
||||
|> Req.get(headers: headers)
|
||||
|> case do
|
||||
{:ok, %{status: status} = response} when status >= 200 and status < 300 ->
|
||||
Converter.convert(resource_module.version(), response.body)
|
||||
|
||||
other ->
|
||||
other
|
||||
end
|
||||
end
|
||||
|
||||
def headers(client, more_headers) do
|
||||
case client.auth_mode do
|
||||
:open ->
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
defmodule Kindling.Config do
|
||||
def root_resources, do: Application.get_env(:kindling, :root_resources, ["Encounter"])
|
||||
def root_resources,
|
||||
do: Application.get_env(:kindling, :root_resources, ["Bundle", "Patient", "Encounter"])
|
||||
end
|
||||
|
|
|
@ -3,31 +3,50 @@ defmodule Kindling.Converter do
|
|||
|
||||
def convert(version_namespace, %{"resourceType" => resource_type} = resource_json) do
|
||||
resource_module = Module.concat(version_namespace, Resource.class_name(resource_type))
|
||||
resource_list_module = Module.concat(version_namespace, "ResourceList")
|
||||
|
||||
structify(resource_module, resource_json)
|
||||
structify(resource_module, resource_list_module, resource_json)
|
||||
end
|
||||
|
||||
def structify(resource_module, resource_json) do
|
||||
def structify(
|
||||
resource_module,
|
||||
resource_list_module,
|
||||
%{"resourceType" => resource_type} = resource_json
|
||||
)
|
||||
when resource_module == resource_list_module do
|
||||
version_namespace =
|
||||
resource_module
|
||||
|> Module.split()
|
||||
|> Enum.reverse()
|
||||
|> tl()
|
||||
|> Enum.reverse()
|
||||
|> Module.concat()
|
||||
|
||||
resource_module = Module.concat(version_namespace, Resource.class_name(resource_type))
|
||||
structify(resource_module, resource_list_module, resource_json)
|
||||
end
|
||||
|
||||
def structify(resource_module, resource_list_module, resource_json) do
|
||||
Code.ensure_loaded!(resource_module)
|
||||
|
||||
atom_map =
|
||||
resource_json
|
||||
|> Enum.map(fn {key_string, value} ->
|
||||
key_atom = key_string |> Recase.to_snake() |> String.to_existing_atom()
|
||||
{key_atom, convert_field(resource_module, key_atom, value)}
|
||||
{key_atom, convert_field(resource_module, resource_list_module, key_atom, value)}
|
||||
end)
|
||||
|> Map.new()
|
||||
|
||||
struct!(resource_module, atom_map)
|
||||
end
|
||||
|
||||
def convert_field(resource_module, field, value) do
|
||||
def convert_field(resource_module, resource_list_module, field, value) do
|
||||
cond do
|
||||
field in resource_module.__schema__(:associations) ->
|
||||
convert_association(resource_module, field, value)
|
||||
convert_association(resource_module, resource_list_module, field, value)
|
||||
|
||||
field in resource_module.__schema__(:embeds) ->
|
||||
convert_embed(resource_module, field, value)
|
||||
convert_embed(resource_module, resource_list_module, field, value)
|
||||
|
||||
field in resource_module.__schema__(:fields) ->
|
||||
cast_field(resource_module, field, value)
|
||||
|
@ -63,27 +82,27 @@ defmodule Kindling.Converter do
|
|||
end
|
||||
end
|
||||
|
||||
def convert_association(resource_module, field, value) do
|
||||
def convert_association(resource_module, resource_list_module, field, value) do
|
||||
%{cardinality: cardinality, related: type} = resource_module.__schema__(:association, field)
|
||||
|
||||
case cardinality do
|
||||
:many ->
|
||||
Enum.map(value, &structify(type, &1))
|
||||
Enum.map(value, &structify(type, resource_list_module, &1))
|
||||
|
||||
:one ->
|
||||
structify(type, value)
|
||||
structify(type, resource_list_module, value)
|
||||
end
|
||||
end
|
||||
|
||||
def convert_embed(resource_module, field, value) do
|
||||
def convert_embed(resource_module, resource_list_module, field, value) do
|
||||
%{cardinality: cardinality, related: type} = resource_module.__schema__(:embed, field)
|
||||
|
||||
case cardinality do
|
||||
:many ->
|
||||
Enum.map(value, &structify(type, &1))
|
||||
Enum.map(value, &structify(type, resource_list_module, &1))
|
||||
|
||||
:one ->
|
||||
structify(type, value)
|
||||
structify(type, resource_list_module, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@ defmodule Kindling.Templates.Functions do
|
|||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/xhtml"}), do: :string
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/markdown"}), do: :string
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/base64Binary"}), do: :string
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/date"}), do: :date
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/dateTime"}), do: :utc_datetime_usec
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/instant"}), do: :utc_datetime_usec
|
||||
def fhir_type_to_ecto(%{"$ref" => "#/definitions/time"}), do: :time_usec
|
||||
|
|
Loading…
Reference in a new issue