View Source Carve.View (Carve v0.3.0)

Carve.View provides a DSL for quickly building JSON API views in Phoenix applications.

It automatically creates show and index functions for Phoenix controllers, handles ID hashing, and manages links between different entities.

Usage

In your Phoenix JSON view module:

defmodule MyApp.UserJSON do
  use Carve.View, :user

  links fn user ->
    %{
      MyApp.TeamJSON => user.team_id,
      MyApp.ProfileJSON => user.profile_id
    }
  end

  get fn id ->
    MyApp.Users.get_by_id!(id)
  end

  view fn user ->
    %{
      id: hash(user.id),
      name: user.name,
      team_id: MyApp.TeamJSON.hash(user.team_id),
      profile_id: MyApp.ProfileJSON.hash(user.profile_id)
    }
  end
end

This will automatically create show/1 and index/1 functions that can be used in your Phoenix controllers, handling both data rendering and link generation.

Generated Functions

The use Carve.View, :type macro generates several functions at compile time:

  • index/1: Handles rendering a list of entities with their links.
  • show/1: Handles rendering a single entity with its links.
  • hash/1: Alias of encode_id.
  • encode_id/1: Encodes an ID using the view type as a salt.
  • decode_id/1: Decodes an ID using the view type as a salt.
  • type_name/0: Returns the type of the view.
  • declare_links/1: Processes links for an entity (if links macro is used).

Here's an example of what these functions might look like at runtime:

def index(%{result: data}) when is_list(data) do
  results = Enum.map(data, &prepare_for_view/1)
  links = Carve.Links.get_links_by_data(__MODULE__, data)
  %{result: results, links: links}
end

def show(%{result: data}) do
  result = prepare_for_view(data)
  links = Carve.Links.get_links_by_data(__MODULE__, data)
  %{result: result, links: links}
end

def hash(id) when is_integer(id), do: Carve.HashIds.encode(:user, id)
def hash(%{id: id}), do: hash(id)

def type_name, do: :user

def declare_links(data) do
  %{
    MyApp.TeamJSON => data.team_id,
    MyApp.ProfileJSON => data.profile_id
  }
end

These generated functions work together to provide a seamless API for rendering JSON views with proper linking and ID hashing.

Summary

Functions

Sets up the view module with the given type.

Defines how to retrieve an entity by its ID.

Defines the links for the current view.

Defines how to render the view for the current entity.

Functions

Link to this macro

__using__(type)

View Source (macro)

Sets up the view module with the given type.

This macro is called when you use use Carve.View, :type in your module. It imports Carve.View functions and sets up the necessary module attributes.

Parameters

  • type: An atom representing the type of the view (e.g., :user, :post).

Example

defmodule MyApp.UserJSON do
  use Carve.View, :user
  # ... rest of the module
end

Defines how to retrieve an entity by its ID.

This macro specifies a function to fetch an entity given its ID.

Parameters

  • func: A function that takes an ID and returns the corresponding entity.

Example

get fn id ->
  MyApp.Users.get_by_id!(id)
end

Defines the links for the current view.

This macro allows you to specify how to generate links for the current entity.

Parameters

  • func: A function that takes the entity data and returns a map of links.

Example

links fn user ->
  %{
    MyApp.TeamJSON => user.team_id,
    MyApp.ProfileJSON => user.profile_id
  }
end

Defines how to render the view for the current entity.

This macro specifies how to format the entity data for JSON output.

Parameters

  • func: A function that takes the entity data and returns a map for JSON rendering.

Example

view fn user ->
  %{
    id: hash(user.id),
    name: user.name,
    team_id: MyApp.TeamJSON.hash(user.team_id)
  }
end