Alembic v2.1.0 Alembic.ResourceIdentifier

A JSON API Resource Identifier.

Summary

Types

t()

A “resource identifier object” is [an %Alembic.ResourceIdentifier{}] that identifies an individual resource.

A “resource identifier object” MUST contain type and id members.

A “resource identifier object” MAY also include a meta member, whose value is a [Alembic.Meta.t] that contains non-standard meta-information.

JSON API - Document Structure - Resource Identifier Object

Types

t :: %Alembic.ResourceIdentifier{id: String.t, meta: Alembic.Meta.t, type: String.t}

A “resource identifier object” is [an %Alembic.ResourceIdentifier{}] that identifies an individual resource.

A “resource identifier object” MUST contain type and id members.

A “resource identifier object” MAY also include a meta member, whose value is a [Alembic.Meta.t] that contains non-standard meta-information.

JSON API - Document Structure - Resource Identifier Object

Functions

from_json(json, error_template)

Specs

from_json(%{String.t => String.t | Alembic.json_object}, Alembic.Error.t) ::
  {:ok, t} |
  Alembic.FromJson.error
from_json(nil | true | false | list | float | integer | String.t, Alembic.Error.t) :: Alembic.FromJson.error

Examples

A resource identifier is valid with "id" and "type"

iex> Alembic.ResourceIdentifier.from_json(
...>   %{"id" => "1", "type" => "shirt"},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{:ok, %Alembic.ResourceIdentifier{id: "1", type: "shirt"}}

A resource identifier can optionally have "meta"

iex> Alembic.ResourceIdentifier.from_json(
...>   %{"id" => "1", "meta" => %{"copyright" => "2015"}, "type" => "shirt"},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{:ok, %Alembic.ResourceIdentifier{id: "1", meta: %{"copyright" => "2015"}, type: "shirt"}}

A resource identifier MUST have an "id"

iex> Alembic.ResourceIdentifier.from_json(
...>   %{"type" => "shirt"},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/data/relationships/shirt/data/id` is missing",
        meta: %{
          "child" => "id"
        },
        source: %Alembic.Source{
          pointer: "/data/relationships/shirt/data"
        },
        status: "422",
        title: "Child missing"
      }
    ]
  }
}

A resource identifer MUST have a "type"

iex> Alembic.ResourceIdentifier.from_json(
...>   %{"id" => "1"},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/data/relationships/shirt/data/type` is missing",
        meta: %{
          "child" => "type"
        },
        source: %Alembic.Source{
          pointer: "/data/relationships/shirt/data"
        },
        status: "422",
        title: "Child missing"
      }
    ]
  }
}

A resource identifer missing both "id" and "type" will show both as missing

iex> Alembic.ResourceIdentifier.from_json(
...>   %{},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/data/relationships/shirt/data/id` is missing",
        meta: %{
          "child" => "id"
        },
        source: %Alembic.Source{
          pointer: "/data/relationships/shirt/data"
        },
        status: "422",
        title: "Child missing"
      },
      %Alembic.Error{
        detail: "`/data/relationships/shirt/data/type` is missing",
        meta: %{
          "child" => "type"
        },
        source: %Alembic.Source{
          pointer: "/data/relationships/shirt/data"
        },
        status: "422",
        title: "Child missing"
      }
    ]
  }
}

A non-resource-identifier will be identified as such

iex> Alembic.ResourceIdentifier.from_json(
...>   [],
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/shirt/data"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/data/relationships/shirt/data` type is not resource identifier",
        meta: %{
          "type" => "resource identifier"
        },
        source: %Alembic.Source{
          pointer: "/data/relationships/shirt/data"
        },
        status: "422",
        title: "Type is wrong"
      }
    ]
  }
}
to_params(resource_identifier, resource_by_id_by_type)

Converts resource_identifier to params format used by Ecto.Changeset.cast/4.

id and type will be used to lookup the attributes in resource_by_id_by_type. Theses attributes and the id will be combined into a map for params

iex> Alembic.ResourceIdentifier.to_params(
...>   %Alembic.ResourceIdentifier{id: "1", type: "author"},
...>   %{
...>     "author" => %{
...>       "1" => %Alembic.Resource{
...>         type: "author",
...>         id: "1",
...>         attributes: %{
...>           "name" => "Alice"
...>         }
...>       }
...>     }
...>   }
...> )
%{
  "id" => "1",
  "name" => "Alice"
}

If no entry is found in resource_by_id_by_type, then only the id is copied to the params. This can happen when the server only wants to send foreign keys.

iex> Alembic.ResourceIdentifier.to_params(
...>   %Alembic.ResourceIdentifier{id: "1", type: "author"},
...>   %{}
...> )
%{
  "id" => "1"
}
to_params(resource_identifier, resource_by_id_by_type, converted_by_id_by_type)

Callback implementation for Alembic.ToParams.to_params/3.