Alembic v4.0.0 Alembic.Links View Source

Where specified, a links member can be used to represent links. The value of each links member MUST be an object (a “links object”).

JSON API - Document Structure - Links

Link to this section Summary

Types

t()

Maps String.t name to Alembic.Link.link

Functions

Validates that the given json follows the spec for “links” and converts any child “links” to Alembic.Link

Converts the links to Alembic.Pagination.t page fields

Link to this section Types

Maps String.t name to Alembic.Link.link

Link to this section Functions

Link to this function from_json(json, error_template) View Source
from_json(Alembic.json_object(), Alembic.Error.t()) ::
  {:ok, map()} | Alembic.FromJson.error()
from_json(nil, Alembic.Error.t()) :: {:ok, nil}
from_json(
  true | false | list() | float() | integer() | String.t(),
  Alembic.Error.t()
) :: Alembic.FromJson.error()

Validates that the given json follows the spec for “links” and converts any child “links” to Alembic.Link.

In a most locations, "links" is optional, so it can be nil.

iex> Alembic.Links.from_json(
...>   nil,
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/links"
...>     }
...>   }
...> )
{:ok, nil}

Links

The value of each links member MUST be an object (a “links object”).

JSON API - Document Structure - Links

iex> Alembic.Links.from_json(
...>   ["http://example.com"],
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/links"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/links` type is not links object",
        meta: %{
          "type" => "links object"
        },
        source: %Alembic.Source{
          pointer: "/links"
        },
        status: "422",
        title: "Type is wrong"
      }
    ]
  }
}

Because the members of a “links object” are free-form, even an empty object is ok

iex> Alembic.Links.from_json(
...>   %{},
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/links"
...>     }
...>   }
...> )
{:ok, %{}}

Link values

Each member of a links object is a “link”. A link MUST be represented as either:

  • a string containing the link’s URL.
  • an object (“link object”) which can contain the following members:

    • href - a string containing the link’s URL.
    • meta - a meta object containing non-standard meta-information about the link.

JSON API - Document Structure - Links

iex> Alembic.Links.from_json(
...>   %{
...>     "string" => "http://example.com",
...>     "link_object" => %{
...>       "href" => "http://example.com",
...>       "meta" => %{
...>         "last_updated_on" => "2015-12-21"
...>       }
...>     }
...>   },
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/links"
...>     }
...>   }
...> )
{
  :ok,
  %{
    "link_object" => %Alembic.Link{
      href: "http://example.com",
      meta: %{
        "last_updated_on" => "2015-12-21"
      }
    },
    "string" => "http://example.com"
  }
}

When any link has an error, then only errors will be returned, but errors from later links will be included

iex> Alembic.Links.from_json(
...>   %{
...>     "first_ok" => "http://example.com/first_ok",
...>     "first_error" => [],
...>     "second_ok" => "http://example.com/second_ok",
...>     "second_error" => []
...>   },
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/links"
...>     }
...>   }
...> )
{
  :error,
  %Alembic.Document{
    errors: [
      %Alembic.Error{
        detail: "`/links/first_error` type is not link object",
        meta: %{
          "type" => "link object"
        },
        source: %Alembic.Source{
          pointer: "/links/first_error"
        },
        status: "422",
        title: "Type is wrong"
      },
      %Alembic.Error{
        detail: "`/links/second_error` type is not link object",
        meta: %{
          "type" => "link object"
        },
        source: %Alembic.Source{
          pointer: "/links/second_error"
        },
        status: "422",
        title: "Type is wrong"
      }
    ]
  }
}
Link to this function to_pagination(links) View Source
to_pagination(nil) :: nil
to_pagination(t()) :: Alembic.Pagination.t()

Converts the links to Alembic.Pagination.t page fields

Single Page

When there is only one page, there will be a "first" and "last" link pointing to the same page, but no “next” or “prev” links.

iex> Alembic.Links.to_pagination(
...>   %{
...>     "first" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
...>     "last" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10"
...>   }
...> )
%Alembic.Pagination{
  first: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  },
  last: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  }
}

Multiple Pages

When there are multiple pages, every page will have a "first" and "last" link pointing to the respective, different pages.

On the first page, the "next" link will be set, but not the "prev" link.

iex> Alembic.Links.to_pagination(
...>   %{
...>     "first" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
...>     "last" => "https://example.com/api/v1/users?page%5Bnumber%5D=3&page%5Bsize%5D=10",
...>     "next" => "https://example.com/api/v1/users?page%5Bnumber%5D=2&page%5Bsize%5D=10"
...>   }
...> )
%Alembic.Pagination{
  first: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  },
  last: %Alembic.Pagination.Page{
    number: 3,
    size: 10
  },
  next: %Alembic.Pagination.Page{
    number: 2,
    size: 10
  }
}

On any middle page, both the "next" and "prev" links will be set.

iex> Alembic.Links.to_pagination(
...>   %{
...>     "first" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
...>     "last" => "https://example.com/api/v1/users?page%5Bnumber%5D=3&page%5Bsize%5D=10",
...>     "next" => "https://example.com/api/v1/users?page%5Bnumber%5D=3&page%5Bsize%5D=10",
...>     "prev" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10"
...>   }
...> )
%Alembic.Pagination{
  first: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  },
  last: %Alembic.Pagination.Page{
    number: 3,
    size: 10
  },
  next: %Alembic.Pagination.Page{
    number: 3,
    size: 10
  },
  previous: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  }
}

On the last page, the "prev" link will be set, but not the "next" link.

iex> Alembic.Links.to_pagination(
...>   %{
...>     "first" => "https://example.com/api/v1/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
...>     "last" => "https://example.com/api/v1/users?page%5Bnumber%5D=3&page%5Bsize%5D=10",
...>     "prev" => "https://example.com/api/v1/users?page%5Bnumber%5D=2&page%5Bsize%5D=10"
...>   }
...> )
%Alembic.Pagination{
  first: %Alembic.Pagination.Page{
    number: 1,
    size: 10
  },
  last: %Alembic.Pagination.Page{
    number: 3,
    size: 10
  },
  previous: %Alembic.Pagination.Page{
    number: 2,
    size: 10
  }
}

If there are no links, then nil will be returned

iex> Alembic.Links.to_pagination(nil)
nil

If there are links, but not for pagination, then nil will be returned

iex> Alembic.Links.to_pagination(%{ "about" => "https://example.com/about" })
nil