首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库支持的REST API与servant?

数据库支持的REST API与servant?
EN

Stack Overflow用户
提问于 2016-08-08 04:56:04
回答 1查看 907关注 0票数 4

我在设置一个简单的概念证明服务API时遇到了一个问题。这是我的用户数据类型和API类型:

代码语言:javascript
复制
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,如下所示:

代码语言:javascript
复制
create u = liftIO $ head <$> returning connection "insert into users (first_name, last_name) values (?,?) returning id" [(first_name u, last_name u)]

已经省略了诸如连接到db和路由方法之类的样板代码。问题是,如果我发出POST请求,我想要做的是创建一个新用户,因此我将提供JSON:

代码语言:javascript
复制
{ "first_name": "jeff", "last_name": "lebowski" }

但是我的程序在运行时会失败,因为

代码语言:javascript
复制
Error in $: When parsing the record User of type Lib.User the key id was not present. 

这是有意义的,因为API指定了一个具有id字段的用户。但是我不想在请求中传递一个假的id (因为它们是由postgres按顺序分配的),因为那是很粗糙的。我也不能将id字段移出用户数据类型,因为当向不同的端点发出GET请求时,postgres-simple会因为模型数据库不匹配而失败(这做了一件显而易见的事情: get by id。不包括在上面)。我在这里做什么?编写自定义FromJson实例?我已经尝试将Data.Aeson.TH选项标志omitNothingFields设置为True,并将id字段设置为Maybe Int,但同样也不起作用。任何建议都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2016-08-08 08:08:55

首先,您需要了解用户和表中对应于此用户的行是两个不同的东西。

行有id,用户没有。例如,您可以想象在不处理ids的情况下比较两个用户,或者考虑它们是否已保存。

一旦被说服,你将不得不向类型系统解释这一点,否则你将不得不处理可能的字段,我认为这不是解决方案。

有些人谈到模板Haskell,我认为它在这里有点夸张,你需要首先解决这个问题。

您可以做的是使用数据类型来表示数据库中保存的行。让我们称它为实体。

代码语言:javascript
复制
newtype PrimaryKey = PrimaryKey Int

data Entity b = Entity PrimaryKey b

然后,在数据库中保存用户行的函数可以接受user作为参数,并返回一个PrimaryKey (当然,在数据库monad中)。从数据库读取数据的其他函数将使用Entity User返回一些内容

您的字段声明不会重复,因为您重用了User类型作为参数。

您必须相应地调整FromRow/ToRow和FromJSON/ToJSON。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38818478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档