我想在Maru中定义一个自定义类型并使用它来解析JSON post实体,并进一步使用它来执行sql语句。但我不知道该怎么做。
这是我的自定义类型
defmodule Maru.Types.Volume do
use Maru.Type
@type length :: Float
@type breadth :: Float
@type height :: Float
end
此类型必须在路由器中使用
defmodule My.Router.Box do
use Maru.Router
alias My.Repo.Box, as: :DB
namespace :select_volume do
params do
requires :volume, type: Volume
post do
volume = DB.getBoxWithRequiredVolume(params)
conn |> put_status(200) |> json(volume)
end
end
然后在这里用于sql查询
defmodule My.Repo.Box do
import Ecto.Query
require Logger
def getBoxWithRequiredVolume(params) do
volume = params[:volume]
query = from box in My.Box,
select: (
%{id: box.id}
),
where: (box.length == ^volume[:length] and box.breadth == ^volume[:breadth] and box.height == ^volume[:height])
query |> My.Repo.all
end
end
这是REST查询的实体:
http://localhost:8880/select_volume
{
"volume":{
"length": 20,
"breadth": 5,
"height": 5
}
}
错误:
%Maru.Exceptions.InvalidFormatter{param: :volume, reason: :illegal,
value: %{"breadth" => 5, "height" => 5, "length" => 20}}
答案 0 :(得分:1)
您需要的不是自定义类型,您只需要使用这样的参数:
params do
requires :volume, type: Map do
requires :length, type: Float
requires :breadth, type: Float
requires :height, type: Float
end
end
然后,您可以从上面发送的请求中获取params
值%{breadth: 5.0, height: 5.0, length: 20.0}
。
答案 1 :(得分:0)
String
s又名binaries
和Atom
s不同。
您传递的值包含二进制文件作为键。格式化程序需要原子(例如:volume[:length]
)。
另外,我建议您对My.Repo.Box.getBoxWithRequiredVolume
进行明确的测试,以确保它返回预期的内容。
旁注:抛出此特定异常的源代码可能会发光:它是Maru.Runtime.do_parse/3
。