限制JSON响应的字段

时间:2016-01-27 11:56:36

标签: json elixir phoenix-framework

我正在使用PhoenixFramework和库Poison。 目前我正在开发REST API。现在我需要以两种不同的方式对模型Book进行编码。

  1. 在所有只包含基本信息(GET /books
  2. 的书籍列表中
  3. 在包含所有信息(GET /book/1
  4. 的详细视图中

    GET /books

    {
      "books": [
        {
          "id": 1,
          "name": "Book one"
        },
        {
          "id": 2,
          "name": "Book two"
        },
        // ...
      ]
    }
    

    GET /books/1

    {
      "book": {
         "id": 1,
         "name": "Book one",
         "description": "This is book one.",
         "author": "Max Mustermann",
        // ...
      }
    }
    

    Book

    的编码器
    defimpl Poison.Encoder, for: MyProject.Book do
    
      @attributes [:id, :name, :description, :author]
    
      def encode(project, _options) do
        project
        |> Map.take(@attributes)
        |> Poison.encode!
      end
    end
    

    代码段控制器

    def index(conn, _params) do
      books = Repo.all(Book)
      json(conn, %{books: books})
    end
    

    如何限制字段?我搜索了:only:exclude这样的选项。 有没有人遇到过这个问题?

    感谢您的帮助!

1 个答案:

答案 0 :(得分:5)

您可以使用render_many/4render_one/4

defmodule MyApp.BookView do

  def render("index.json", %{books: books}) do
    render_many(books, __MODULE__, "book.json")
  end

  def render("show.json", %{book: book}) do
    render_one(book, __MODULE__, "full_book.json")
  end

  def render("book.json", %{book: book}) do
    %{
      id: book.id,
      name: book.name
    }
  end


  def render("full_book.json", %{book: book}) do
    %{
      id: book.id,
      name: book.name,
      description: description,
      author: book.author
      ...
    }
  end
end

请注意,分配中的名称(渲染的第二个参数)由模块决定。有关使用其他名称的示例,请参阅Render many to many relationship JSON in Phoenix Framework

然后您可以使用以下命令从控制器中调用:

render(conn, "index.json", books: Repo.all(Book))

render(conn, "show.json", book: Repo.get(Book, 1))