Bangun API GraphQL dengan bahasa fungsional favorit Anda!
Morpheus GraphQL (Server & Client) membantu Anda membangun API GraphQL di Haskell dengan tipe Haskell asli. Morpheus akan mengonversi tipe Haskell Anda menjadi skema GraphQL dan semua pemecah Anda hanyalah fungsi Haskell asli. Morpheus GraphQL juga dapat mengonversi skema graphql Anda atau permintaan ke tipe Haskell dan memvalidasi dalam waktu kompilasi.
Morpheus masih dalam tahap awal pengembangan, jadi umpan balik apa pun lebih dari disambut, dan kami menghargai kontribusi apa pun! Cukup buka masalah di sini di GitHub, atau bergabunglah dengan saluran Slack kami untuk menghubungi kami.
Harap dicatat bahwa file readme ini hanya memberikan pengantar singkat ke perpustakaan. Jika Anda tertarik dengan topik yang lebih maju, kunjungi dokumen.
Sejak versi v0.28.0, Morpheus GraphQL mengimplementasikan [ https://github.com/enisdenjo/graphql-ws/blob/master/protocol.md Air. https://github.com/apollographql/subscriptions-transport-ws/blob/master/protocol.md protocol.
Untuk memulai dengan Morpheus, pertama -tama Anda harus menambahkannya ke dependensi proyek Anda, sebagai berikut (dengan asumsi Anda menggunakan hpack):
paket.yml
dependencies :
- morpheus-graphql
- morpheus-graphql-core
- morpheus-graphql-subscriptionsSelain itu, Anda harus memberi tahu Stack versi mana yang akan dipilih:
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 menghasilkan jenis: Query , Deity , DeityArgs , yang dapat digunakan dengan rootResolver
descriptions dan deprecations akan ditampilkan dalam introspeksi.
importGQLDocumentWithNamespace akan menghasilkan jenis dengan bidang namespaced. Jika Anda tidak memerlukan namespace, gunakan importGQLDocument
Untuk mendefinisikan API GraphQL dengan Morpheus kita mulai dengan mendefinisikan skema API sebagai tipe data Haskell asli, yang memperoleh kelas tipe Generic . Menggunakan Ekstensi Bahasa DeriveAnyClass Kami kemudian juga mendapatkan contoh untuk kelas tipe GQLType . Bidang yang malas diatasi pada jenis Query ini didefinisikan melalui a -> ResolverQ () IO b , mewakili penyelesaian satu set argumen a ke nilai konkret 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 ) Untuk setiap bidang dalam jenis Query yang ditentukan melalui a -> mb (seperti deity ) kami akan mendefinisikan implementasi resolver yang menyediakan nilai selama runtime dengan mengacu pada beberapa sumber data, misalnya database atau API lain. Bidang yang didefinisikan tanpa a -> mb Anda hanya dapat memberikan nilai.
Dalam contoh di atas, bidang DeityArgs juga dapat dinamai menggunakan identitas yang dipesan (seperti: type , where , dll), untuk menghindari konflik, simbol utama ( ' ) harus dilampirkan. Misalnya, Anda dapat memiliki:
data DeityArgs = DeityArgs
{ name :: Text -- Required Argument
, mythology :: Maybe Text -- Optional Argument
, type' :: Text
} deriving ( Generic , GQLType ) Nama bidang dalam permintaan akhir akan menjadi type alih -alih type' . Parser permintaan Morpheus mengubah masing -masing identitas yang dipesan di Haskell 2010 ke nama yang sesuai secara internal. Ini juga berlaku untuk pilihan.
resolveDeity :: DeityArgs -> ResolverQ () IO Deity
resolveDeity DeityArgs { name, mythology } = liftEither $ dbDeity name mythology
askDB :: Text -> Maybe Text -> IO ( Either String Deity )
askDB = ... Untuk membuat tipe Query ini tersedia sebagai API, kami mendefinisikan RootResolver dan memberinya makan ke interpreter Morpheus. RootResolver terdiri dari query , mutation dan definisi subscription , sementara kami menghilangkan yang terakhir untuk contoh ini:
rootResolver :: RootResolver IO () Query Undefined Undefined
rootResolver =
RootResolver
{ queryResolver = Query {deity = resolveDeity}
, mutationResolver = Undefined
, subscriptionResolver = Undefined
}
gqlApi :: ByteString -> IO ByteString
gqlApi = interpreter rootResolver Seperti yang Anda lihat, API didefinisikan sebagai ByteString -> IO ByteString yang dapat kita panggil secara langsung atau gunakan di dalam kerangka web yang sewenang -wenang seperti scotty atau serverless-haskell . Kami akan pergi untuk scotty dalam contoh ini:
main :: IO ()
main = scotty 3000 $ post " /api " $ raw =<< (liftIO . gqlApi =<< body) Jika kita sekarang mengirim permintaan pos ke http://localhost:3000/api dengan kueri graphql sebagai contoh dalam alat seperti Insomnia :
query GetDeity {
deity ( name : " Morpheus " ) {
fullName
power
}
}Kueri kami akan diselesaikan!
{
"data" : {
"deity" : {
"fullName" : " Morpheus " ,
"power" : " Shapeshifting "
}
}
} Jika Anda tertarik untuk membuat API Morpheus GraphQL dengan Serverless , Anda harus melihat contoh kami di repositori ini: Mythology API Ini adalah contoh proyek kami dengan Morpheus GraphQL dan Serverless-Haskell , di mana Anda dapat menanyakan karakter mitologi yang berbeda dengan GraphiQL .
Mythology API digunakan di: api.morpheusgraphql.com di mana Anda dapat mengujinya dengan GraphiQL
Di bawah ini adalah daftar proyek menggunakan Morpheus GraphQL. Jika Anda ingin mulai menggunakan Morpheus GraphQL, mereka adalah templat yang baik untuk memulai.
Edit bagian ini dan kirim PR jika Anda ingin membagikan proyek Anda .
Morpheus adalah dewa Yunani dari tidur dan mimpi yang namanya berasal dari kata Yunani μορφή bentuk atau bentuk yang berarti. Dia dikatakan dapat meniru bentuk yang berbeda dan GraphQL bagus dalam melakukan hal itu: mengubah data dalam bentuk banyak API yang berbeda.
Morpheus ditulis dan dikelola oleh Nalchevanidze