{"id":20080625,"url":"https://github.com/bluzky/json_view","last_synced_at":"2025-05-05T23:31:19.417Z","repository":{"id":42003562,"uuid":"384649000","full_name":"bluzky/json_view","owner":"bluzky","description":"Elixir library to render Json with relationship","archived":false,"fork":false,"pushed_at":"2022-04-19T09:02:45.000Z","size":18,"stargazers_count":30,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-24T05:36:53.332Z","etag":null,"topics":["elixir","elixir-phoenix","json-serializer","json-view","phoenix-elixir"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluzky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-10T08:26:41.000Z","updated_at":"2024-06-12T05:42:14.000Z","dependencies_parsed_at":"2022-08-12T02:01:02.096Z","dependency_job_id":null,"html_url":"https://github.com/bluzky/json_view","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluzky%2Fjson_view","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluzky%2Fjson_view/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluzky%2Fjson_view/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluzky%2Fjson_view/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluzky","download_url":"https://codeload.github.com/bluzky/json_view/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252593016,"owners_count":21773388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-phoenix","json-serializer","json-view","phoenix-elixir"],"created_at":"2024-11-13T15:29:22.166Z","updated_at":"2025-05-05T23:31:19.121Z","avatar_url":"https://github.com/bluzky.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JsonView\n\n**Render json easier with relationship and custom data rendering**\n\n## Installation\n\nThe package can be installed\nby adding `json_view` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:json_view, \"~\u003e 0.2.0\"}\n  ]\nend\n```\n\nDocumentation can be found at [https://hexdocs.pm/json_view](https://hexdocs.pm/json_view).\n\n\n## How to use it\n\n  Normally, you query data from database then render to JSON and return to client, and you might want to:\n\n  - Keep the original value\n  - Return value in a new format, or return some calculated data\n  - Render relationships that defined by Ecto schema\n\n  JsonView helps to render json data easier by support relationship and custom render data.\n  Most of the time you may want to add it to your view:\n\n```elixir\n  def view do\n    quote do\n      ...\n      use JsonView\n      ...\n    end\n  end\n```\n\n  Or you can use it directly on your view\n\n```elixir\n  defmodule MyApp.UserView do\n      use JsonView\n      def render(\"user.json\", %{user: user}) do\n      \trender_json(user, [:first_name, :last_name, :vatar], [], [])\n      end\n  end\n      \n  defmodule MyApp.PostView do\n      use JsonView\n\n      # define which fields return without modifying\n      @fields [:title, :content, :excerpt, :cover]\n      # define which fields that need to format or calculate, you have to define `render_field/2` below\n      @custom_fields [:like_count]\n      # define which view used to render relationship\n      @relationships [author: MyApp.UserView]\n\n      def render(\"post.json\", %{post: post}) do\n          # 1st way if `use JsonView`\n          render_json(post, @fields, @custom_fields, @relationships)\n      end\n\n      def render_field(:like_count, item) do\n          # load like_count from some where\n      end\n  end\n```\n\nAnd then use it\n\n```elixir\npost = %Post{\n\ttitle: \"Hello JsonView\",\n\texcerpt: \"Now you can render Json easier\",\n\tcontent: \"Install and put it to work\",\n\tcover: nil,\n\tinserted_at: ~N[2021-07-05 00:00:00],\n\tupdated_at: ~N[2021-07-09 00:00:00],\n\tauthor: %User{\n\t\tfirst_name: \"Daniel\",\n\t\tlast_name: \"James\",\n\t\temail: \"daniel@example.com\",\n\t\tavatar: nil,\n\t\tinserted_at: ~N[2021-06-30 00:00:00]\n\t\tupdated_at: ~N[2021-07-02 00:00:00]\n\t}\n}\n\nMyApp.PostView.render(\"post.json\", %{post: post})\n\n# or invoke from PostController\nrender(conn, \"post.json\", post: post)\n```\n\n\n\nThis is the result that you can use to return from PhoenixController\n\n```elixir\n%{\n\ttitle: \"Hello JsonView\",\n\texcerpt: \"Now you can render Json easier\",\n\tcontent: \"Install and put it to work\",\n\tcover: nil,\n  like_count: nil,\n\tauthor: %{\n\t\tfirst_name: \"Daniel\",\n\t\tlast_name: \"James\"\n\t}\n}\n```\n\n\n\n\n\n## How to define fields and relationships\n\n- **Custom field**\n\n  ```elixir\n  @custom_fields [:like_count]\n  # this invokes `render(:like_count, post)`\n  \n  @custom_fields [like_count: \u0026my_function/1]\n  # this invokes `my_function.(post)`\n  ```\n\n- **Relationship**\n\n  ```elixir\n  @relationships [author: MyApp.UserView]\n  # this invokes `MyApp.UserView.render(\"user.json\", %{user: user})`\n  \n  @relationships [author: {MyApp.UserView, \"basic_profile.json\"}]\n  # this invokes `MyApp.UserView.render(\"basic_profile.json\", %{user: user})`\n  ```\n\n\n\n## Data override\n\n  `JsonView` render `fields` -\u003e `custom_fields` -\u003e `relationships`. If they define same field, then the latter will override the prior\n\n\n\n## Default fields\n\n  You can pass a list of default `fields` and/or `custom_fields` as options to `use JsonView`. These fields then merged to `fields` and `custom_fields` before rendering data each time you invoke `render_json`\n\n```elixir\n  use JsonView, fields: [:id, :updated_at], custom_fields: [inserted_at: \u0026to_local_time/2]\n```\n\n\n\n## Render hook\n\n  You can pass a function to process data after `JsonView` completes rendering like this:\n\n```elixir\n  use JsonView, after_render: \u0026convert_all_datetime_to_local/1\n\n  def convert_all_datetime_to_local(data) do\n    Enum.map(data, fn {k, v} -\u003e\n      v =\n        case v do\n          %NaiveDateTime{} -\u003e to_local_datetime(v)\n          _ -\u003e v\n        end\n      {k, v}\n    end)\n    |\u003e Enum.into(%{})\n  end\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluzky%2Fjson_view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluzky%2Fjson_view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluzky%2Fjson_view/lists"}