我在设置一个简单的概念证明服务 API 时遇到了问题。这是我的用户数据类型和我的 API 类型:
data User = User { id :: Int, first_name :: String, last_name :: String } deriving (Eq, Show, Generic)
instance FromRow User
instance ToRow User
$(deriveJSON defaultOptions ''User)
type API = "users" :> ReqBody '[JSON] User :> Post '[JSON] User
处理程序方法使用 postgresql-simple,如下所示:
create u = liftIO $ head <$> returning connection "insert into users (first_name, last_name) values (?,?) returning id" [(first_name u, last_name u)]
已经省略了连接数据库和路由方法等样板代码。问题是,如果我发出 POST 请求,我想做的是创建一个新用户,所以我会提供 JSON:
{ "first_name": "jeff", "last_name": "lebowski" }
但是然后我的程序在运行时失败了
Error in $: When parsing the record User of type Lib.User the key id was not present.
这是有道理的,因为 API 指定了一个具有 id 字段的用户。但我不想在请求中传递一个虚假的 id(因为它们是由 postgres 顺序分配的),因为那很恶心。我也无法将 id 字段移出 User 数据类型,因为在向不同的端点发出 GET 请求时,由于模型数据库不匹配而导致 postgres-simple 失败(这很明显:通过 id 获取。不包括在上面)。我在这里做什么?编写自定义 FromJson 实例?我已经尝试将 Data.Aeson.TH 选项标志 omitNothingFields 设置为 True 并将 id 字段设置为 Maybe Int,但这也不起作用。任何意见,将不胜感激。