- Notifications
You must be signed in to change notification settings - Fork4
Lexing, parsing, pretty-printing, and metaprogramming facilities for dealing with GraphQL schemas and queries
License
NotificationsYou must be signed in to change notification settings
dmjio/graphql-meta
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
AGraphQL toolkit providing the following:
- AlexLexer of the
GraphQL
lexical specification. - HappyParser of the
GraphQL
BNF Grammar. - Pretty printer of the
GraphQL
abstract syntax tree (AST) for human consumption. - QuickCheck generators for creating random AST fragments
- Used in conjunction with pretty printing to establish round trip property tests.
- Source
- Generics implementation providing correct-by-construction
Schema
at compile time. - QuasiQuoter providing inline definitions of
ExecutableDefinitions
.
{-#LANGUAGE QuasiQuotes #-}moduleMain (main)whereimportGraphQL.QQ (query)main::IO()main=print [query| { building (id: 123) {floorCount, id}} |]
QueryDocument {getDefinitions= [DefinitionOperation (AnonymousQuery [SelectionField (FieldNothing (Name {unName="building"}) [Argument (Name {unName="id"}) (ValueInt123)][] [SelectionField (FieldNothing (Name {unName="floorCount"})[][][]) ,SelectionField (FieldNothing (Name {unName="id"})[][][]) ])]) ]}
GraphQLExecutableDefinition
abstract syntax tree rewriting is made possible via Template Haskell's metavariable substitution. DuringQuasiQuotation
all unbound variables in aGraphQL
query that have identical names inside the current scope will automatically be translated intoGraphQL
AST terms and substituted.
buildingQuery::Int->ExecutableDefinitionbuildingQuery buildingId= [query| { building (id: $buildingId) {floorCount, id}} |]
QueryDocument {getDefinitions= [DefinitionOperation (AnonymousQuery [SelectionField (FieldNothing (Name {unName="building"}) [Argument (Name {unName="buildingId"}) (ValueInt4)][] [SelectionField (FieldNothing (Name {unName="floorCount"})[][][]) ,SelectionField (FieldNothing (Name {unName="id"})[][][]) ])]) ]}
It is possible to derive GraphQL schema usingGHC.Generics
.Simply importGHC.Generics
, deriveGeneric
(must enable theDeriveGeneric
language extension) and make an instance ofToObjectTypeDefintion
.See below for an example:
{-#LANGUAGE DeriveGeneric #-}moduleMainwhereimportGHC.Generics (Generic)importGraphQL.Internal.Syntax.Encoder (schemaDocument)importData.Proxy (Proxy)importqualifiedData.Text.IOasTimportGraphQL.Generic (ToObjectTypeDefinition(..))dataPerson=Person{name::String ,age::Int}deriving (Show,Eq,Generic)instanceToObjectTypeDefinitionPersonshowPersonSchema::IO()showPersonSchema=print$ toObjectTypeDefinition (Proxy@Person)-- type Person{name:String!,age:Int!}
- Generic deriving is currently only supported on product types with record field selectors.
- Only
ObjectTypeDefintion
is currently supported.
- Generic deriving of
ScalarTypeDefintion
andEnumTypeDefintion
.
- Inspired by@edsko's workQuasi-quoting DSLs for free.
Alex
andHappy
lexing & parsing inspired byconfig-value
BSD3 2018-2019 Urbint Inc.