使用您喜欢的功能语言构建GraphQl API!
morpheus graphql(服务器和客户端)可帮助您在Haskell中构建具有本机Haskell类型的Haskell中的GraphQl API。 Morpheus将使您的Haskell类型转换为GraphQL模式,并且您所有的解析器都是本机Haskell功能。 morpheus graphQl还可以将您的GraphQL模式转换为Haskell类型,并在编译时间验证它们。
Morpheus仍处于发展的早期阶段,因此任何反馈都非常受欢迎,我们感谢任何贡献!只需在Github上打开一个问题,或加入我们的Slack频道以与您联系。
请注意,此读数文件仅提供对库的简短介绍。如果您对更高级的主题感兴趣,请访问文档。
由于版本v0.28.0,morpheus graphQl实现了[https://github.com/enisdenjo/graphql-ws/blob/blob/master/master/protocol.md](GraphqlQl-ws graphQl graphql claphQl consobetsonects),并且不再使用该协议https://github.com/apollographql/subscriptions-transport-ws/blob/master/protocol.md协议。
为了开始使用morpheus,您首先需要将其添加到项目的依赖项中,如下(假设您使用的是HPACK):
package.yml
dependencies :
- morpheus-graphql
- morpheus-graphql-core
- morpheus-graphql-subscriptions此外,您应该告诉stack选择哪个版本:
stack.yml
resolver : lts-16.2
extra-deps :
- morpheus-graphql-0.28.0
- morpheus-graphql-core-0.28.0
- morpheus-graphql-app-0.28.0
- morpheus-graphql-code-gen-0.28.0
- morpheus-graphql-code-gen-utils-0.28.0
- morpheus-graphql-server-0.28.0
- morpheus-graphql-client-0.28.0
- morpheus-graphql-subscriptions-0.28.0schema.gql
type Query {
deity ( name : String ! = " Morpheus " ): Deity !
}
"""
Description for Deity
"""
type Deity {
"""
Description for name
"""
name : String !
power : String @deprecated ( reason : " some reason for " )
}API.HS
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module API ( api ) where
import Data.ByteString.Lazy.Char8 ( ByteString )
import Data.Morpheus ( interpreter )
import Data.Morpheus.Document ( importGQLDocument )
import Data.Morpheus.Types ( RootResolver ( .. ), Undefined ( .. ))
import Data.Text ( Text )
importGQLDocument " schema.gql "
rootResolver :: RootResolver IO () Query Undefined Undefined
rootResolver =
RootResolver
{ queryResolver = Query {deity},
mutationResolver = Undefined ,
subscriptionResolver = Undefined
}
where
deity DeityArgs {name} =
pure
Deity
{ name = pure name,
power = pure ( Just " Shapeshifting " )
}
api :: ByteString -> IO ByteString
api = interpreter rootResolver template Haskell生成类型: Query , Deity , DeityArgs ,可以由rootResolver使用
descriptions和deprecations将在内省显示。
importGQLDocumentWithNamespace将生成具有名称空间字段的类型。如果您不需要命名空间,请使用importGQLDocument
为了定义使用morpheus的GraphQl API,我们首先将API架构定义为本机Haskell数据类型,该数据类型衍生了Generic类型类。然后,使用DeriveAnyClass语言扩展,我们还会得出GQLType类型类的实例。该Query类型上的懒惰分解字段是通过a -> ResolverQ () IO b定义的,代表将一组参数a解析为具体值b 。
data Query m = Query
{ deity :: DeityArgs -> m Deity
} deriving ( Generic , GQLType )
data Deity = Deity
{ fullName :: Text -- Non-Nullable Field
, power :: Maybe Text -- Nullable Field
} deriving ( Generic , GQLType )
data DeityArgs = DeityArgs
{ name :: Text -- Required Argument
, mythology :: Maybe Text -- Optional Argument
} deriving ( Generic , GQLType )对于通过a -> mb定义的Query类型中的每个字段(如deity ),我们将定义一个解析器实现,该实现通过参考某些数据源,例如数据库或其他API来提供运行时提供值。在没有a -> mb情况下定义的字段您只能提供一个值。
在上面的示例中,也可以使用保留的身份(例如: type , where等)命名DeityArgs的字段,以避免冲突,必须附上一个素符号( ' )。例如,您可以拥有:
data DeityArgs = DeityArgs
{ name :: Text -- Required Argument
, mythology :: Maybe Text -- Optional Argument
, type' :: Text
} deriving ( Generic , GQLType )最终请求中的字段名称将是type而不是type' 。 Morpheus请求解析器将Haskell 2010中的每个保留身份转换为其内部的相应名称。这也适用于选择。
resolveDeity :: DeityArgs -> ResolverQ () IO Deity
resolveDeity DeityArgs { name, mythology } = liftEither $ dbDeity name mythology
askDB :: Text -> Maybe Text -> IO ( Either String Deity )
askDB = ...为了使此Query类型可作为API可用,我们定义一个RootResolver并将其馈送到morpheus interpreter中。 RootResolver由query , mutation和subscription定义组成,而我们省略了此示例的后者:
rootResolver :: RootResolver IO () Query Undefined Undefined
rootResolver =
RootResolver
{ queryResolver = Query {deity = resolveDeity}
, mutationResolver = Undefined
, subscriptionResolver = Undefined
}
gqlApi :: ByteString -> IO ByteString
gqlApi = interpreter rootResolver如您所见,API定义为ByteString -> IO ByteString ,我们可以直接调用或在诸如scotty或serverless-haskell之类的任意网络框架内使用。在此示例中,我们将去scotty :
main :: IO ()
main = scotty 3000 $ post " /api " $ raw =<< (liftIO . gqlApi =<< body)如果我们现在将邮政请求发送到http://localhost:3000/api则具有GraphQl查询为正文,例如在Insomnia之类的工具中:
query GetDeity {
deity ( name : " Morpheus " ) {
fullName
power
}
}我们的查询将得到解决!
{
"data" : {
"deity" : {
"fullName" : " Morpheus " ,
"power" : " Shapeshifting "
}
}
}如果您有兴趣使用Serverless创建Morpheus GraphQL API,则应在此存储库中查看我们的示例:神话API ,这是我们使用Morpheus GraphQL和Serverless-Haskell示例项目构建,您可以在其中查询不同的神话GraphiQL 。
神话API在以下部署: api.morpheusgraphql.com ,您可以在其中使用GraphiQL对其进行测试
以下是使用morpheus graphql的项目列表。如果您想开始使用morpheus graphQl,则它们是一个很好的模板。
编辑本节并发送PR,如果您想共享您的项目。
Morpheus是希腊的睡眠和梦想之神,其名字来自希腊语μορφή的意思或形状。据说他能够模仿不同的形式,而GraphQl擅长做到这一点:以许多不同API的形状转换数据。
Morpheus由Nalchevanidze编写和维护