通过graphql-api处理程序进行映射

时间:2017-04-10 21:54:12

标签: haskell graphql haskell-graphql

我一直在尝试使用the Haskell graphql-api library,它使用一些servant样式类型技巧来表示类型级别的GraphQL API。它提供Handler类型系列,用于提供GraphQL API的实际实现。我已经为测试目的创建了一个简单的API:

type Query = Object "Query" '[]
  '[ Argument "id" Text :> Field "test" (Maybe Foo) ]

type Foo = Object "Foo" '[]
  '[ Field "name" Text ]

我还有一个代表Foo资源的Haskell类型,以及一个从数据库中检索它的函数:

data ServerFoo = ServerFoo
  { name :: Text
  } deriving (Eq, Show)

lookupFoo :: Text -> IO (Maybe ServerFoo)

现在,我想为Handler实施Query。首先,我为Handler实施了Foo

viewFoo :: ServerFoo -> Handler IO Foo
viewFoo ServerFoo { name } = pure $ pure name

然后我去实现了根处理程序,但是当我最终得到viewFoo时,我意识到我不确定如何使用我的Maybe ServerFoo函数。我试过这个:

handler :: Handler IO Query
handler = pure $ \fooId -> do
  foo <- lookupFoo fooId
  sequence $ fmap viewFoo foo

然而,这不起作用。它会产生以下类型错误:

• Couldn't match type ‘IO Text’
                 with ‘Object "Foo" '[] '[Field "name" Text]’
  Expected type: ServerFoo
                 -> IO (Object "Foo" '[] '[Field "name" Text])
    Actual type: ServerFoo -> Handler IO Foo
• In the first argument of ‘fmap’, namely ‘viewFoo’
  In the second argument of ‘($)’, namely ‘fmap viewFoo foo’
  In a stmt of a 'do' block: (sequence $ fmap viewFoo foo)

这对我来说似乎有些奇怪,因为我读过的例子似乎暗示Handler被设计为成分。事实上,他们似乎是,因为做一些调整以删除Maybe使得这个类型检查:

type Query = Object "Query" '[]
  '[ Argument "id" Text :> Field "test" Foo ]

handler :: Handler IO Query
handler = pure $ \fooId -> do
  Just foo <- lookupFoo fooId
  viewFoo foo

然而,显然,这涉及到部分模式匹配,所以这不是一个好的解决方案。

我的结论是Handler IO不是算子,或Handler m (Maybe a)比我预期的更奇怪。不管是什么原因,这似乎是一个相当简单的用例,所以我想有必要有一些解决方案。

0 个答案:

没有答案