{"id":13686999,"url":"https://github.com/morpheusgraphql/morpheus-graphql","last_synced_at":"2025-04-04T15:10:34.465Z","repository":{"id":34761170,"uuid":"169793481","full_name":"morpheusgraphql/morpheus-graphql","owner":"morpheusgraphql","description":"Haskell GraphQL Api, Client and Tools","archived":false,"fork":false,"pushed_at":"2024-06-30T20:33:08.000Z","size":12093,"stargazers_count":409,"open_issues_count":11,"forks_count":63,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-10-29T17:14:18.554Z","etag":null,"topics":["graphql","graphql-api","graphql-client","graphql-haskell","graphql-introspection","graphql-server","graphql-subscriptions","haskell","haskell-graphql","web"],"latest_commit_sha":null,"homepage":"https://morpheusgraphql.com","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/morpheusgraphql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["nalchevanidze"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2019-02-08T20:18:45.000Z","updated_at":"2024-09-28T04:49:39.000Z","dependencies_parsed_at":"2024-11-15T13:02:50.785Z","dependency_job_id":null,"html_url":"https://github.com/morpheusgraphql/morpheus-graphql","commit_stats":{"total_commits":754,"total_committers":48,"mean_commits":"15.708333333333334","dds":0.136604774535809,"last_synced_commit":"65e854660bb95fc7f3ff592b1f97404ddc31a981"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morpheusgraphql%2Fmorpheus-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morpheusgraphql%2Fmorpheus-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morpheusgraphql%2Fmorpheus-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morpheusgraphql%2Fmorpheus-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morpheusgraphql","download_url":"https://codeload.github.com/morpheusgraphql/morpheus-graphql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247198463,"owners_count":20900080,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-api","graphql-client","graphql-haskell","graphql-introspection","graphql-server","graphql-subscriptions","haskell","haskell-graphql","web"],"created_at":"2024-08-02T15:00:45.832Z","updated_at":"2025-04-04T15:10:34.446Z","avatar_url":"https://github.com/morpheusgraphql.png","language":"Haskell","readme":"# Morpheus GraphQL [![Hackage](https://img.shields.io/hackage/v/morpheus-graphql.svg)](https://hackage.haskell.org/package/morpheus-graphql) ![CI](https://github.com/morpheusgraphql/morpheus-graphql/workflows/CI/badge.svg)\n\nBuild GraphQL APIs with your favorite functional language!\n\nMorpheus GraphQL (Server \u0026 Client) helps you to build GraphQL APIs in Haskell with native Haskell types.\nMorpheus 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.\n\nMorpheus is still in an early stage of development, so any feedback is more than welcome, and we appreciate any contribution!\nJust open an issue here on GitHub, or join [our Slack channel](https://morpheus-graphql.slack.com) to get in touch.\n\nPlease note that this readme file provides only a brief introduction to the library. If you are interested in more advanced topics, visit [Docs](https://morpheusgraphql.com/).\n\nSince version v0.28.0, Morpheus GraphQL implements the [https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md](graphql-ws GraphQL over WebSocket Protocol), and *no longer* uses the [https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md](subscriptions-transport-ws) protocol.\n\n## Getting Started\n\n### Setup\n\nTo get started with Morpheus, you first need to add it to your project's dependencies, as follows (assuming you're using hpack):\n\n_package.yml_\n\n```yaml\ndependencies:\n  - morpheus-graphql\n  - morpheus-graphql-core\n  - morpheus-graphql-subscriptions\n```\n\nAdditionally, you should tell stack which version to pick:\n\n_stack.yml_\n\n```yaml\nresolver: lts-16.2\n\nextra-deps:\n- morpheus-graphql-0.28.0\n- morpheus-graphql-core-0.28.0\n- morpheus-graphql-app-0.28.0\n- morpheus-graphql-code-gen-0.28.0\n- morpheus-graphql-code-gen-utils-0.28.0\n- morpheus-graphql-server-0.28.0\n- morpheus-graphql-client-0.28.0\n- morpheus-graphql-subscriptions-0.28.0\n```\n\n### Building your first GraphQL API\n\n### with GraphQL syntax\n\n_schema.gql_\n\n```gql\ntype Query {\n  deity(name: String! = \"Morpheus\"): Deity!\n}\n\n\"\"\"\nDescription for Deity\n\"\"\"\ntype Deity {\n  \"\"\"\n  Description for name\n  \"\"\"\n  name: String!\n  power: String @deprecated(reason: \"some reason for\")\n}\n```\n\n_API.hs_\n\n```haskell\n{-# LANGUAGE DeriveGeneric #-}\n{-# LANGUAGE DuplicateRecordFields #-}\n{-# LANGUAGE FlexibleContexts #-}\n{-# LANGUAGE FlexibleInstances #-}\n{-# LANGUAGE MultiParamTypeClasses #-}\n{-# LANGUAGE NamedFieldPuns #-}\n{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE TypeFamilies #-}\n\nmodule API (api) where\n\nimport Data.ByteString.Lazy.Char8 (ByteString)\nimport Data.Morpheus (interpreter)\nimport Data.Morpheus.Document (importGQLDocument)\nimport Data.Morpheus.Types (RootResolver (..), Undefined (..))\nimport Data.Text (Text)\n\nimportGQLDocument \"schema.gql\"\n\nrootResolver :: RootResolver IO () Query Undefined Undefined\nrootResolver =\n  RootResolver\n    { queryResolver = Query {deity},\n      mutationResolver = Undefined,\n      subscriptionResolver = Undefined\n    }\n  where\n    deity DeityArgs {name} =\n      pure\n        Deity\n          { name = pure name,\n            power = pure (Just \"Shapeshifting\")\n          }\n\napi :: ByteString -\u003e IO ByteString\napi = interpreter rootResolver\n```\n\nTemplate Haskell Generates types: `Query` , `Deity`, `DeityArgs`, that can be used by `rootResolver`\n\n`descriptions` and `deprecations` will be displayed in introspection.\n\n`importGQLDocumentWithNamespace` will generate Types with namespaced fields. If you don't need namespace use `importGQLDocument`\n\n### with Native Haskell Types\n\nTo define a GraphQL API with Morpheus we start by defining the API Schema as a native Haskell data type,\nwhich derives the `Generic` type class. Using the `DeriveAnyClass` language extension we then also derive instances for the `GQLType` type class. Lazily resolvable fields on this `Query` type are defined via `a -\u003e ResolverQ () IO b`, representing resolving a set of arguments `a` to a concrete value `b`.\n\n```haskell\ndata Query m = Query\n  { deity :: DeityArgs -\u003e m Deity\n  } deriving (Generic, GQLType)\n\ndata Deity = Deity\n  { fullName :: Text         -- Non-Nullable Field\n  , power    :: Maybe Text   -- Nullable Field\n  } deriving (Generic, GQLType)\n\ndata DeityArgs = DeityArgs\n  { name      :: Text        -- Required Argument\n  , mythology :: Maybe Text  -- Optional Argument\n  } deriving (Generic, GQLType)\n```\n\nFor each field in the `Query` type defined via `a -\u003e m b` (like `deity`) we will define a resolver implementation that provides the values during runtime by referring to\nsome data source, e.g. a database or another API. Fields that are defined without `a -\u003e m b` you can just provide a value.\n\nIn 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:\n\n```haskell\ndata DeityArgs = DeityArgs\n  { name      :: Text        -- Required Argument\n  , mythology :: Maybe Text  -- Optional Argument\n  , type'     :: Text\n  } deriving (Generic, GQLType)\n```\n\nThe 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.\n\n```haskell\nresolveDeity :: DeityArgs -\u003e ResolverQ () IO Deity\nresolveDeity DeityArgs { name, mythology } = liftEither $ dbDeity name mythology\n\naskDB :: Text -\u003e Maybe Text -\u003e IO (Either String Deity)\naskDB = ...\n```\n\nTo 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:\n\n```haskell\nrootResolver :: RootResolver IO () Query Undefined Undefined\nrootResolver =\n  RootResolver\n    { queryResolver = Query {deity = resolveDeity}\n    , mutationResolver = Undefined\n    , subscriptionResolver = Undefined\n    }\n\ngqlApi :: ByteString -\u003e IO ByteString\ngqlApi = interpreter rootResolver\n```\n\nAs you can see, the API is defined as `ByteString -\u003e IO ByteString` which we can either invoke directly or use inside an arbitrary web framework\nsuch as `scotty` or `serverless-haskell`. We'll go for `scotty` in this example:\n\n```haskell\nmain :: IO ()\nmain = scotty 3000 $ post \"/api\" $ raw =\u003c\u003c (liftIO . gqlApi =\u003c\u003c body)\n```\n\nIf we now send a POST request to `http://localhost:3000/api` with a GraphQL Query as body for example in a tool like `Insomnia`:\n\n```GraphQL\nquery GetDeity {\n  deity (name: \"Morpheus\") {\n    fullName\n    power\n  }\n}\n```\n\nour query will be resolved!\n\n```JSON\n{\n  \"data\": {\n    \"deity\": {\n      \"fullName\": \"Morpheus\",\n      \"power\": \"Shapeshifting\"\n    }\n  }\n}\n```\n\n## Serverless Example\n\nIf you are interested in creating a `Morpheus GraphQL` API with `Serverless`, you should take a look at our example in this repository:\n[_Mythology API_](https://github.com/morpheusgraphql/mythology-api) it is our example project build with `Morpheus GraphQL` and `Serverless-Haskell`,\nwhere you can query different mythology characters with `GraphiQL`.\n\nMythology API is deployed on : [_api.morpheusgraphql.com_](https://api.morpheusgraphql.com) where you can test it with `GraphiQL`\n\n![Mythology Api](https://morpheusgraphql.com/assets/img/mythology-api.png \"mythology-api\")\n\n## Showcase\n\nBelow are the list of projects using Morpheus GraphQL. If you want to start using Morpheus GraphQL, they are\ngood templates to begin with.\n\n- https://github.com/morpheusgraphql/mythology-api\n  - Serverless Mythology API\n- https://github.com/dandoh/web-haskell\n  - Modern webserver boilerplate in Haskell: Morpheus Graphql + Postgresql + Authentication + DB migration + Dotenv and more\n\n_Edit this section and send PR if you want to share your project_.\n\n# About\n\n## The name\n\n_Morpheus_ is the greek god of sleep and dreams whose name comes from the greek word _μορφή_ meaning form or shape.\nHe is said to be able to mimic different forms and GraphQL is good at doing exactly that: Transforming data in the shape\nof many different APIs.\n\n## Team\n\nMorpheus is written and maintained by [_nalchevanidze_](https://github.com/nalchevanidze)\n\n## Roadmap\n\n- Medium future:\n  - Stabilize API\n  - Specification-isomorphic error handling\n- Long term:\n  - Support all possible GQL features\n  - Performance optimization\n","funding_links":["https://github.com/sponsors/nalchevanidze"],"categories":["Haskell","Implementations"],"sub_categories":["Haskell"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorpheusgraphql%2Fmorpheus-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorpheusgraphql%2Fmorpheus-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorpheusgraphql%2Fmorpheus-graphql/lists"}