【问题标题】:Custom JSON response format in PhoenixPhoenix 中的自定义 JSON 响应格式
【发布时间】:2017-09-10 05:56:06
【问题描述】:

Phoenix 似乎有一种非常规的方式来序列化 JSON(无论如何这对我来说都是新的)。例如,假设我有一个包含两列的表 - id 和 name。在几乎所有其他 Web 框架中,对 show 端点的响应都会返回如下所示的 JSON:

{
    "id": 1,
    "name": "foo"
}

使用 Phoenix 生成器,响应如下所示:

{
    "data": 
    {
        "id": 1,
        "name": "foo"
    }
}

我在 POST 中看到了类似的问题,我需要发布 {"company": { "name": "foo" } } 而不是 { "name": "foo" }

我有两个问题:

  1. 以这种我不知道的方式序列化 JSON 是否有优势?
  2. 有没有办法以上述“正常”方式处理 JSON 序列化?

【问题讨论】:

  • 按照您的方式,您如何表示响应中的错误?
  • 客户端主要使用 HTTP 状态码。有关更多详细信息,他们可以查看响应正文,通常是 JSON。

标签: json elixir phoenix-framework


【解决方案1】:
  1. 我认为这取决于个人喜好。

  2. 当然可以改。

在生成的视图中,将其更改为

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

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

在你的控制器函数中接受来自以下的 JSON:

def create(conn, %{"company" => %{"name" => name}}) do
  ...
end

def create(conn, %{"name" => name}) do
  ...
end

您生成的函数可能看起来不同,但我认为您明白了。

【讨论】:

  • 1.不完全正确:使用这种方法,您还必须在控制器中定义每一列(create 函数),因此更难维护。
  • 您不必进行模式匹配。您还可以将整个 params 映射传递到您的变更集中,并让它选择所需的键。
  • @Phillipp 这让我非常接近。我如何处理update 控制器方法的签名,因为id 来自路径而company_params 来自请求正文?目前是def update(conn, %{"id" => id, "company" => company_params})
  • @user140550 它们应该混合在一起,因此您可以在 %{"id" => id, "name" => name} 上进行模式匹配。
【解决方案2】:

发布 Phoenix 1.3.0 生成代码的差异,以便对其他人有所帮助:

控制器变化

-  def create(conn, %{"company" => company_params}) do
+  def create(conn, company_params) do

-  def update(conn, %{"id" => id, "company" => company_params}) do
-    company = Repo.get!(Company, id)
+  def update(conn, company_params) do
+    company = Repo.get!(Company, conn.path_params["id"])

查看更改

   def render("index.json", %{companies: companies}) do
-    %{data: render_many(companies, ConstructApi.CompanyView, "company.json")}
+    render_many(companies, ConstructApi.CompanyView, "company.json")
   end

   def render("show.json", %{company: company}) do
-    %{data: render_one(company, ConstructApi.CompanyView, "company.json")}
+    render_one(company, ConstructApi.CompanyView, "company.json")
   end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    相关资源
    最近更新 更多