使用您喜歡的功能語言構建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編寫和維護