限制JSON响应的字段

Fab*_*755 2 json elixir phoenix-framework

我正在使用PhoenixFramework和图书馆毒药.目前我正在开发REST API.现在我需要以Book两种不同的方式对模型进行编码.

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

GET /books

{
  "books": [
    {
      "id": 1,
      "name": "Book one"
    },
    {
      "id": 2,
      "name": "Book two"
    },
    // ...
  ]
}
Run Code Online (Sandbox Code Playgroud)

GET /books/1

{
  "book": {
     "id": 1,
     "name": "Book one",
     "description": "This is book one.",
     "author": "Max Mustermann",
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

编码器 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
Run Code Online (Sandbox Code Playgroud)

片段控制器

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

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

感谢帮助!

Gaz*_*ler 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
Run Code Online (Sandbox Code Playgroud)

请注意,分配中的名称(渲染的第二个参数)由模块决定.有关使用其他名称的示例,请参阅Phoenix Framework中的渲染多对多关系JSON.

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

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

render(conn, "show.json", book: Repo.get(Book, 1))
Run Code Online (Sandbox Code Playgroud)