All Projects â†’ morpheusgraphql â†’ Morpheus Graphql

morpheusgraphql / Morpheus Graphql

Licence: mit
Haskell GraphQL Api, Client and Tools

Programming Languages

3896 projects

Projects that are alternatives of or similar to Morpheus Graphql

36 Graphql Concepts
📜 36 concepts every GraphQL developer should know.
Stars: ✭ 209 (-26.67%)
Mutual labels:  graphql, graphql-server, graphql-api, graphql-subscriptions, graphql-client
[NOT MAINTAINED]An API integration framework using GraphQL
Stars: ✭ 182 (-36.14%)
Mutual labels:  graphql, graphql-server, graphql-api, graphql-client
✨⚡️ A beautiful feature-rich GraphQL Client for all platforms.
Stars: ✭ 3,827 (+1242.81%)
Mutual labels:  graphql, graphql-server, graphql-subscriptions, graphql-client
Graphql Stack
A visual explanation of how the various tools in the GraphQL ecosystem fit together.
Stars: ✭ 117 (-58.95%)
Mutual labels:  graphql, graphql-server, graphql-api, graphql-client
A Node.js framework for creating GraphQL API servers easily and without a lot of boilerplate.
Stars: ✭ 194 (-31.93%)
Mutual labels:  graphql, graphql-server, graphql-api, graphql-subscriptions
Hangzhou Graphql Party
杭州 GraphQLParty 往期记录(slide,照片,预告,视频等)
Stars: ✭ 142 (-50.18%)
Mutual labels:  graphql, graphql-server, graphql-api
Monorepo of the PoP project, including: a server-side component model in PHP, a GraphQL server, a GraphQL API plugin for WordPress, and a website builder
Stars: ✭ 160 (-43.86%)
Mutual labels:  graphql, graphql-server, graphql-api
GraphQL to REST converter: automatically generate a RESTful API from your existing GraphQL API
Stars: ✭ 181 (-36.49%)
Mutual labels:  graphql, graphql-server, graphql-api
Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
Stars: ✭ 3,009 (+955.79%)
Mutual labels:  graphql, graphql-server, graphql-client
Wp Graphql
🚀 GraphQL API for WordPress
Stars: ✭ 3,097 (+986.67%)
Mutual labels:  graphql, graphql-server, graphql-api
Graphql Spqr Spring Boot Starter
Spring Boot 2 starter powered by GraphQL SPQR
Stars: ✭ 187 (-34.39%)
Mutual labels:  graphql, graphql-server, graphql-api
Rails Devise Graphql
A Rails 6 boilerplate to create your next Saas product. Preloaded with graphQL, devise, JWT, CanCanCan, RailsAdmin, Rubocop, Rspec, i18n and more.
Stars: ✭ 199 (-30.18%)
Mutual labels:  graphql, graphql-server, graphql-api
Django Channels based WebSocket GraphQL server with Graphene-like subscriptions
Stars: ✭ 203 (-28.77%)
Mutual labels:  graphql, graphql-server, graphql-subscriptions
QLens is an electron app which dynamically generates GraphQL Schemas and Mongo Schema visualization. QLens significantly cuts development time by automating the formation of their GraphQL schemas based on information fetched from their non-relational database.
Stars: ✭ 110 (-61.4%)
Mutual labels:  graphql, graphql-server, graphql-client
Storefront Api
Storefront GraphQL API Gateway. Modular architecture. ElasticSearch included. Works great with Magento1, Magento2, Spree, OpenCart, Pimcore and custom backends
Stars: ✭ 180 (-36.84%)
Mutual labels:  graphql, graphql-server, graphql-api
Daptin - Backend As A Service - GraphQL/JSON-API Headless CMS
Stars: ✭ 1,195 (+319.3%)
Mutual labels:  graphql, graphql-server, graphql-api
Want to use GraphQL with Clojure/script but don't want keBab or snake_keys everywhere? Use locksmith to change all the keys!
Stars: ✭ 59 (-79.3%)
Mutual labels:  graphql, graphql-server, graphql-client
Haskell GraphQL implementation
Stars: ✭ 36 (-87.37%)
Mutual labels:  graphql, graphql-server, graphql-api
Graphql Kotlin
Libraries for running GraphQL in Kotlin
Stars: ✭ 1,030 (+261.4%)
Mutual labels:  graphql, graphql-server, graphql-client
A Clojure & JVM library for developing GraphQL API instantly from Postgres and MySQL databases
Stars: ✭ 240 (-15.79%)
Mutual labels:  graphql, graphql-server, graphql-api

Morpheus GraphQL Hackage CI

Build GraphQL APIs with your favorite functional language!

Morpheus GraphQL (Server & Client) helps you to build GraphQL APIs in Haskell with native Haskell types. Morpheus will convert your Haskell types to a GraphQL schema and all your resolvers are just native Haskell functions. Morpheus GraphQL can also convert your GraphQL Schema or Query to Haskell types and validate them in compile time.

Morpheus is still in an early stage of development, so any feedback is more than welcome, and we appreciate any contribution! Just open an issue here on GitHub, or join our Slack channel to get in touch.

Getting Started


To get started with Morpheus, you first need to add it to your project's dependencies, as follows (assuming you're using hpack):


  - morpheus-graphql

Additionally, you should tell stack which version to pick:


resolver: lts-16.2

  - morpheus-graphql-0.17.0

As Morpheus is quite new, make sure stack can find morpheus-graphql by running stack upgrade and stack update

Building your first GraphQL API

with GraphQL syntax


type Query {
  deity(name: String! = "Morpheus"): Deity!

Description for Deity
type Deity {
  Description for name
  name: String!
  power: String @deprecated(reason: "some reason for")


{-# 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 =
    { queryResolver = Query {deity},
      mutationResolver = Undefined,
      subscriptionResolver = Undefined
    deity DeityArgs {name} =
          { name = pure name,
            power = pure (Just "Shapeshifting")

api :: ByteString -> IO ByteString
api = interpreter rootResolver

Template Haskell Generates types: Query , Deity, DeityArgs, that can be used by rootResolver

descriptions and deprecations will be displayed in introspection.

importGQLDocumentWithNamespace will generate Types with namespaced fields. If you don't need namespace use importGQLDocument

with Native Haskell Types

To define a GraphQL API with Morpheus we start by defining the API Schema as a native Haskell data type, which derives the Generic typeClass. Lazily resolvable fields on this Query type are defined via a -> ResolverQ () IO b, representing resolving a set of arguments a to a concrete value 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)

For each field in the Query type defined via a -> m b (like deity) we will define a resolver implementation that provides the values during runtime by referring to some data source, e.g. a database or another API. Fields that are defined without a -> m b you can just provide a value.

In above example, the field of DeityArgs could also be named using reserved identities (such as: type, where, etc), in order to avoid conflict, a prime symbol (') must be attached. For example, you can have:

data DeityArgs = DeityArgs
  { name      :: Text        -- Required Argument
  , mythology :: Maybe Text  -- Optional Argument
  , type'     :: Text
  } deriving (Generic)

The field name in the final request will be type instead of type'. The Morpheus request parser converts each of the reserved identities in Haskell 2010 to their corresponding names internally. This also applies to selections.

resolveDeity :: DeityArgs -> ResolverQ e () Deity
resolveDeity DeityArgs { name, mythology } = liftEither $ dbDeity name mythology

askDB :: Text -> Maybe Text -> IO (Either String Deity)
askDB = ...

To make this Query type available as an API, we define a RootResolver and feed it to the Morpheus interpreter. A RootResolver consists of query, mutation and subscription definitions, while we omit the latter for this example:

rootResolver :: RootResolver IO () Query Undefined Undefined
rootResolver =
    { queryResolver = Query {deity = resolveDeity}
    , mutationResolver = Undefined
    , subscriptionResolver = Undefined

gqlApi :: ByteString -> IO ByteString
gqlApi = interpreter rootResolver

As you can see, the API is defined as ByteString -> IO ByteString which we can either invoke directly or use inside an arbitrary web framework such as scotty or serverless-haskell. We'll go for scotty in this example:

main :: IO ()
main = scotty 3000 $ post "/api" $ raw =<< (liftIO . gqlApi =<< body)

If we now send a POST request to http://localhost:3000/api with a GraphQL Query as body for example in a tool like Insomnia:

query GetDeity {
  deity (name: "Morpheus") {

our query will be resolved!

  "data": {
    "deity": {
      "fullName": "Morpheus",
      "power": "Shapeshifting"

Serverless Example

If you are interested in creating a Morpheus GraphQL API with Serverless, you should take a look at our example in this repository: Mythology API it is our example project build with Morpheus GraphQL and Serverless-Haskell, where you can query different mythology characters with GraphiQL.

Mythology API is deployed on : where you can test it with GraphiQL

Mythology Api

Advanced topics


You can use Union Types as Enums, but they're not allowed to have any parameters.

data City
  = Athens
  | Sparta
  | Corinth
  | Delphi
  | Argos
  deriving (Generic)

instance GQLType City where
  type KIND City = ENUM

Union types

To use union type, all you have to do is derive the GQLType class. Using GraphQL fragments, the arguments of each data constructor can be accessed from the GraphQL client.

data Character
  = CharacterDeity Deity -- will be unwrapped, since Character + Deity = CharacterDeity
  | SomeDeity Deity -- will be wrapped since Character + Deity != SomeDeity
  | Creature { creatureName :: Text, creatureAge :: Int }
  | Demigod Text Text
  | Zeus
  deriving (Generic, GQLType)

where Deity is an object.

As we see, there are different kinds of unions. Morpheus handles them all.

This type will be represented as

union Character = Deity | SomeDeity | Creature | SomeMulti | Zeus

type SomeDeity {
  _0: Deity!

type Creature {
  creatureName: String!
  creatureAge: Int!

type Demigod {
  _0: Int!
  _1: String!

type Zeus {
  _: Unit!

By default, union members will be generated with wrapper objects. There is one exception to this: if a constructor of a type is the type name concatenated with the name of the contained type, it will be referenced directly. That is, given:

data Song = { songName :: Text, songDuration :: Float } deriving (Generic, GQLType)

data Skit = { skitName :: Text, skitDuration :: Float } deriving (Generic, GQLType)

data WrappedNode
  = WrappedSong Song
  | WrappedSkit Skit
  deriving (Generic, GQLType)

data NonWrapped
  = NonWrappedSong Song
  | NonWrappedSkit Skit
  deriving (Generic, GQLType)

You will get the following schema:

# has wrapper types
union WrappedNode = WrappedSong | WrappedSkit

# is a direct union
union NonWrapped = Song | Skit

type WrappedSong {
  _0: Song!

type WrappedSKit {
  _0: Skit!

type Song {
  songDuration: Float!
  songName: String!

type Skit {
  skitDuration: Float!
  skitName: String!
  • for all other unions will be generated new object type. for types without record syntax, fields will be automatically indexed.

  • all empty constructors in union will be summed in type <tyConName>Enum (e.g CharacterEnum), this enum will be wrapped in CharacterEnumObject and added to union members.

Scalar types

To use custom scalar types, you need to provide implementations for parseValue and serialize respectively.

data Odd = Odd Int  deriving (Generic)

instance DecodeScalar Euro where
  decodeScalar (Int x) = pure $ Odd (... )
  decodeScalar _ = Left "invalid Value!"

instance EncodeScalar Euro where
  encodeScalar (Odd value) = Int value

instance GQLType Odd where
  type KIND Odd = SCALAR

Applicative and Monad instance

The Resolver type has Applicative and Monad instances that can be used to compose resolvers.


Morpheus converts your schema to a GraphQL introspection automatically. You can use tools like Insomnia to take a look at the introspection and validate your schema. If you need a description for your GQLType inside of the introspection you can define the GQLType instance manually and provide an implementation for the description function:

data Deity = Deity
{ ...
} deriving (Generic)

instance GQLType Deity where
  description = const "A supernatural being considered divine and sacred"

screenshots from Insomnia

alt text alt text alt text

Handling Errors

for errors you can use use either liftEither or MonadFail: at the and they have same result.

with liftEither

resolveDeity :: DeityArgs -> ResolverQ e IO Deity
resolveDeity DeityArgs {} = liftEither $ dbDeity

dbDeity ::  IO Either Deity
dbDeity = pure $ Left "db error"

with MonadFail

resolveDeity :: DeityArgs -> ResolverQ e IO Deity
resolveDeity DeityArgs { } = fail "db error"


In addition to queries, Morpheus also supports mutations. They behave just like regular queries and are defined similarly:

newtype Mutation m = Mutation
  { createDeity :: MutArgs -> m Deity
  } deriving (Generic, GQLType)

rootResolver :: RootResolver IO  () Query Mutation Undefined
rootResolver =
    { queryResolver = Query {...}
    , mutationResolver = Mutation { createDeity }
    , subscriptionResolver = Undefined
      -- Mutation Without Event Triggering
      createDeity :: MutArgs -> ResolverM () IO Deity
      createDeity_args = lift setDBAddress

gqlApi :: ByteString -> IO ByteString
gqlApi = interpreter rootResolver


In morpheus subscription and mutation communicate with Events, Event consists with user defined Channel and Content.

Every subscription has its own Channel by which it will be triggered

data Channel
  = ChannelA
  | ChannelB

data Content
  = ContentA Int
  | ContentB Text

type MyEvent = Event Channel Content

newtype Query m = Query
  { deity :: m Deity
  } deriving (Generic)

newtype Mutation m = Mutation
  { createDeity :: m Deity
  } deriving (Generic)

newtype Subscription (m ::  * -> * ) = Subscription
  { newDeity :: m  Deity
  } deriving (Generic)

newtype Subscription (m :: * -> *) = Subscription
{ newDeity :: SubscriptionField (m Deity),
deriving (Generic)

type APIEvent = Event Channel Content

rootResolver :: RootResolver IO APIEvent Query Mutation Subscription
rootResolver = RootResolver
  { queryResolver        = Query { deity = fetchDeity }
  , mutationResolver     = Mutation { createDeity }
  , subscriptionResolver = Subscription { newDeity }
  -- Mutation Without Event Triggering
  createDeity :: ResolverM EVENT IO Address
  createDeity = do
      publish [Event { channels = [ChannelA], content = ContentA 1 }]
      lift dbCreateDeity
  newDeity :: SubscriptionField (ResolverS EVENT IO Deity)
  newDeity = subscribe ChannelA $ do
    -- executed only once
    -- immediate response on failures
    pure $ \(Event _ content) -> do
        -- executes on every event
        lift (getDBAddress content)


  1. defining interface with Haskell Types (runtime validation):

      -- interface is just regular type derived as interface
    newtype Person m = Person {name ::  m Text}
      deriving (Generic)
    instance GQLType (Person m) where
      type KIND (Person m) = INTERFACE
    -- with GQLType user can links interfaces to implementing object
    instance GQLType Deity where
      implements _ = [interface (Proxy @Person)]
  2. defining with importGQLDocument and DSL (compile time validation):

    interface Account {
      name: String!
    type User implements Account {
      name: String!

Morpheus GraphQL Client with Template haskell QuasiQuotes

    query GetHero ($character: Character)
        deity (fatherOf:$character) {
          worships {
            deity2Name: name

with schema:

input Character {
  name: String!

type Deity {
  name: String!
  worships: Deity
  power: Power!

enum Power {

will validate query and Generate:

  • namespaced response and variable types
  • instance for Fetch typeClass
data GetHero = GetHero {
  deity: DeityDeity

-- from: {user
data DeityDeity = DeityDeity {
  name: Text,
  worships: Maybe DeityWorshipsDeity
  power: Power

-- from: {deity{worships
data DeityWorshipsDeity = DeityWorshipsDeity {
  name: Text,

data Power =
  | PowerTeleportation
  | PowerOmniscience

data GetHeroArgs = GetHeroArgs {
  character: Character

data Character = Character {
  name: Person

as you see, response type field name collision can be handled with GraphQL alias.

with fetch you can fetch well typed response GetHero.

  fetchHero :: Args GetHero -> m (Either String GetHero)
  fetchHero = fetch jsonRes args
        args = GetHeroArgs {character = Person {name = "Zeus"}}
        jsonRes :: ByteString -> m ByteString
        jsonRes = <GraphQL APi>

in this case, jsonRes resolves a request into a response in some monad m.

A fetch resolver implementation against a real API may look like the following:

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Char8 as C8
import Network.HTTP.Req

resolver :: String -> ByteString -> IO ByteString
resolver tok b = runReq defaultHttpConfig $ do
    let headers = header "Content-Type" "application/json"
    responseBody <$> req POST (https "") (ReqBodyLbs b) lbsResponse headers

this is demonstrated in examples/src/Client/StarWarsClient.hs

types can be generated from introspection too:

defineByIntrospectionFile "./introspection.json"

Morpheus CLI for Code Generating

you should use morpheus-graphql-cli


Below are the list of projects using Morpheus GraphQL. If you want to start using Morpheus GraphQL, they are good templates to begin with.

Edit this section and send PR if you want to share your project.


The name

Morpheus is the greek god of sleep and dreams whose name comes from the greek word μορφή meaning form or shape. He is said to be able to mimic different forms and GraphQL is good at doing exactly that: Transforming data in the shape of many different APIs.


Morpheus is written and maintained by nalchevanidze


  • Medium future:
    • Stabilize API
    • Specification-isomorphic error handling
  • Long term:
    • Support all possible GQL features
    • Performance optimization
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].