Moprheus GraphQL supports the import of GQL schemas directly into Haskell code based on Template Haskell.
for client you can use declareGlobalTypes and declareLocalTypes from Data.Morpheus.Client.
-- defines input and enum types
declareGlobalTypes "./schema.gql"
-- defines types for query
declareLocalTypes "./schema.gql" "./query.gql"
for server you can use importGQLDocument from Data.Morpheus.Document
importGQLDocument "./schema.gql"
Moprheus GraphQL also supports generating code from GraphQL
documents. To do this, you should first install
the morpheus-graphql-code-gen package from hackage or dowload built binary from releases. to get a correct result,
make sure that the package versions match.
the package provides morpheus cli with commands build and check .
The build command generates files from the GQL source files
contained in the code-gen.yaml configuration for the specified project root.
However, the check command only checks if the generated files match the existing GQL documents,
which is quite handy to check if the files are outdated.
Let's take a look at the following project. where we have different posts and users and want to develop an application for client and server.
├── package.yaml
├── code-gen.yaml
└── src
├── Main.hs
├── Scalars.hs
├── Server
| └── Blog.gql
└── Client
├── Blog.gql
└── Queries
├── GetPosts.gql
└── GetUsers.gqlfiles are defined as follows.
./src/Scalars.hs
newtype Markdown = Markdown Text
deriving
( Show,
Generic,
Eq
)
instance GQLType Markdown where
type KIND Markdown = SCALAR
instance DecodeScalar Markdown where
decodeScalar (String x) = pure (Markdown x)
decodeScalar _ = fail "not suppoorted"
instance EncodeScalar Markdown where
encodeScalar (Markdown x) = String x
instance FromJSON Markdown where
parseJSON = scalarFromJSON
instance ToJSON Markdown where
toJSON = scalarToJSON
./src/Server/Blog.gql & ./src/Client/Blog.gql
scalar Markdown
type Post {
title: String!
body: Markdown
}
type User {
name: String!
posts: [Post!]!
}
type Query {
getUsers: [User!]!
getPosts: [Post!]!
}
./src/Client/Queries/GetPosts.gql
query GetPosts {
getPosts {
title
body
}
}
./src/Client/Queries/GetUsers.gql
query GetUsers {
getUsers {
name
posts {
title
body
}
}
}
to generate files from it, we should now configure code-gen.yaml.
./code-gen.yaml
server:
- name: Server API # Name of the service
source: ./src # root folder for haskell source files
includes:
- path: Server/**/*.gql # list of gql sources
externals:
Markdown: Scalars # imports Markdown type declatation from Scalars.hs
client:
- name: Client API # Name of the service
source: ./src # root folder for haskell source files
schema: Client/Blog.gql
includes:
- path: Client/Queries/**/*.gql # list of gql sources
externals:
Markdown: Scalars # imports Markdown type declatation from Scalars.hs
now we are ready to generate types.
build command
morpheus build ./
command will lookup code-gen.yaml and generate coresponding Haskell modules.
it will also print out the processed documents listed in these services.
build:Server API
- src/Server/Blog.gql
build:Client API
- src/Client/Blog.gql
- src/Client/Queries/GetPosts.gql
- src/Client/Queries/GetUsers.gql
OK
the generated files are.
|── src
├── Server
| └── Blog.hs
└── Client
├── Blog.hs
└── Queries
├── GetPosts.hs
└── GetUsers.hsNow you can import types and write your own handlers or client queries based on them. For the full implementation of the example, see code-gen-docs.