Skip to content

Releases: morpheusgraphql/morpheus-graphql

morpheus-graphql-0.12.0

21 May 22:31
5225224
Compare
Choose a tag to compare
Pre-release

morpheus-graphql

Breaking Changes

Package was extracted as:

  • morpheus-graphql-core: core components like: parser, validator, executor, utils.

    • Data.Morpheus.Core
    • Data.Morpheus.QuasiQuoter
    • Data.Morpheus.Error
    • Data.Morpheus.Internal.TH
    • Data.Morpheus.Internal.Utils
    • Data.Morpheus.Types.Internal.Resolving
    • Data.Morpheus.Types.Internal.Operation
    • Data.Morpheus.Types.Internal.AST
    • Data.Morpheus.Types.IO
  • morpheus-graphql-client: lightweight version of morpheus client without server implementation

    • Data.Morpheus.Client
  • morpheus-graphql: morpheus graphql server

    • Data.Morpheus
    • Data.Morpheus.Kind
    • Data.Morpheus.Types
    • Data.Morpheus.Server
    • Data.Morpheus.Document

deprecated:

  • Res, IORes, ResolveQ : use ResolverQ
  • MutRes, IOMutRes, ResolveM : use ResolverM
  • SubRes, IOSubRes, ResolveS: use ResolverS
  • failRes: use MonadFail

New Feature

  • Semigroup support for Resolver

  • MonadFail Support for Resolver

  • flexible resolvers: ResolverO, ResolverQ , RwsolverM, ResolverS
    they can handle object and scalar types:

    -- if we have record and regular Int
    data Object m = Object { field :: m Int }
    
    -- we canwrite
    -- handes kind : (* -> *) -> *
    resolveObject :: ResolverO o EVENT IO Object
    -- is alias to: Resolver o () IO (Object (Resolver o () IO))
    -- or
    -- handes kind : *
    resolveInt :: ResolverO o EVENT IO Int
    -- is alias to: Resolver o () IO Int

    the resolvers : ResolverQ , RwsolverM, ResolverS , are like
    ResolverO but with QUERY , MUTATION and SUBSCRIPTION as argument.

  • flexible compsed Resolver Type alias: ComposedResolver. extends ResolverO with
    parameter (f :: * -> *). so that you can compose Resolvers e.g:

    resolveList :: ComposedResolver o EVENT IO [] Object
    -- is alias to: Resolver o () IO [Object (Resolver o () IO))]
    
    resolveList :: ComposedResolver o EVENT IO Maybe Int
    -- is alias to: Resolver o () IO (Maybe Int)
  • server supports interfaces (see Readme):

    1. define interface with Haskell Types (runtime validation):
    2. define interface with importGQLDocument and DSL (compile time validation):
  • support default directives: @skip and @include

  • SelectionTree interface

minor

  • fixed subscription sessions, srarting new session does not affects old ones.
  • added tests for subscriptions

morpheus-graphql-core

0.12.0 - 21.05.2020

New features

  • parser supports implemnets interfaces seperated with empty spaces

    type T implements A , B C & D {
  • introspection can render interfaces

morpheus-graphql-0.11.0

01 May 09:30
3dbcfb6
Compare
Choose a tag to compare
Pre-release

Breaking Changes

  • Client generated enum data constructors are now prefixed with with the type name to avoid name conflicts.

  • for Variant selection inputUnion uses inputname insead of __typename

  • in Data.Morpheus.Server

    • gqlSocketApp and gqlSocketMonadIOApp are replaced with webSocketsApp
    • removed initGQLState, GQLState
  • for better control of subscriptions

    • replaced instance interpreter gqlRoot state with
      interpreter gqlRoot.
    • added: Input, Stream, httpPubApp

    from now on you can define API that can be
    used in websockets as well as in http servers

    api :: Input api -> Stream api EVENT IO
    api = interpreter gqlRoot
    
    server :: IO ()
    server = do
      (wsApp, publish) <- webSocketsApp api
      let httpApp = httpPubApp api publish
      ...
      runBoth wsApp httpApp

    where publish :: e -> m ()

    websockets and http app do not have to be on the same server.
    e.g. you can pass events between servers with webhooks.

  • subscription can select only one top level field (based on the GraphQL specification).

New features

  • Instead of rejecting conflicting selections, they are merged (based on the GraphQL specification).
  • Support for input lists separated by newlines. thanks @charlescrain
  • conflicting variable , fragment ... validation
  • issue #411: Aeson FromJSON ToJSON instances for ID

minor

  • changes to internal types
  • fixed validation of apollo websockets requests

morpheus-graphql-0.10.0

07 Jan 16:40
7c4bc7c
Compare
Choose a tag to compare
Pre-release

Breaking Changes

  • all constructors of Resolver: QueryResolver,MutResolver,SubResolver are unexposed. use lift , publish or subscribe instead.
    e.g

    -- Query Resolver
    resolveUser :: ResolveQ EVENT IO User
    resolveUser = lift getDBUser
    
    -- Mutation Resolver
    resolveCreateUser :: ResolveM EVENT IO User
    resolveCreateUser = do
      publish [userUpdate] -- publishes event inside mutation
      lift setDBUser
    
    -- Subscription Resolver
    resolveNewUser :: ResolveS EVENT IO User
    resolveNewUser = subscribe [USER] $ do
      pure $ \(Event _ content) -> lift (getDBUserByContent content)

New features

  • exposed publish for mutation resolvers, now you can write

    resolveCreateUser :: ResolveM EVENT IO User
    resolveCreateUser = do
        requireAuthorized
        publish [userUpdate]
        liftEither setDBUser
  • exposed subscribe for subscription resolvers, now you can write

    resolveNewUser :: ResolveS EVENT IO User
    resolveNewUser = subscribe [USER] $ do
        requireAuthorized
        pure userByEvent
      where userByEvent (Event _ content) = liftEither (getDBUser content)
  • type SubField will convert your subscription monad to query monad.
    SubField (Resolver Subscription Event IO) User will generate same as
    Resolver Subscription Event IO (User ((Resolver QUERY Event IO)))

    now if you can define subscription as follows

    data Subscription m = Subscription {
      newUser :: SubField m User
    }
  • unsafeInternalContext to get resolver context, use only if it really necessary.
    the code depending on it may break even on minor version changes.

    resolveUser :: ResolveQ EVENT IO User
    resolveUser = do
      Context { currentSelection, schema, operation } <- unsafeInternalContext
      lift (getDBUser currentSelection)

Minor

  • MonadIO instance for resolvers. Thanks @dandoh
  • Example using STM, authentication, monad transformers. Thanks @dandoh
  • added dependency mtl

morpheus-graphql-0.9.1

02 Jan 07:03
9e6bd03
Compare
Choose a tag to compare
Pre-release

Changed

  • removed dependency mtl

morpheus-graphql-0.9.0

01 Jan 19:27
07d3c29
Compare
Choose a tag to compare
Pre-release

Added

  • WithOperation constraint for Generic Resolvers (#347) thanks @dandoh

Fixed

  • liftEither support in MutResolver (#351)

  • selection of __typename on object und union objects (#337)

  • auto inferece of external types in gql document (#343)

    th will generate field m (Type m) if type has an argument

    e.g for this types and DSL

    data Type1 = Type1 { ... }
    type Type2 m = SomeType m
    data Type3 m = Type2 { bla :: m Text } deriving ...
    type Query {
      field1 : Type1!
      field2 : Type2!
      field3 : Type3!
    }

    morpheus generates

    data Query m = Query {
      field1 :: m Type1
      field2 :: m (Type2 m)
      field3 :: m (Type3 m)
    } deriving ...

    now you can combine multiple gql documents:

    importDocumentWithNamespace `coreTypes.gql`
    importDocumentWithNamespace `operations.gql`

Changed

  • support of resolver fields m type for the fields without arguments

    data Diety m = Deity {
        name :: m Text
    }
    -- is equal to
    data Diety m = Deity {
        name :: () -> m Text
    }
  • template haskell generates m type insead of () -> m type for fields without argument (#334)

    data Diety m = Deity {
        name :: (Arrow () (m Text)),
        power :: (Arrow () (m (Maybe Text)))
    }
    -- changed to
    data Diety m = Deity {
        name :: m Text,
        power :: m (Maybe Text)
    }

morpheus-graphql-0.8.0

15 Dec 01:49
3034ac7
Compare
Choose a tag to compare
Pre-release

Changed

  • deprecated: INPUT_OBJECT, OBJECT, UNION,

    • use INPUT instead of INPUT_OBJECT
    • use deriving(GQLType) insead of OBJECT or UNION
  • only namespaced Unions generate regular graphql Union, other attempts will be wrapped inside an object with constructor name :

    e.g:

    data Character = 
      CharacterDeity Deity
      SomeDeity Deity
      deriving (GQLType)

    where Deity is Object.
    will generate

      union CHaracter = Deity | SomeDeity
    
      type SomeDeity {
        _0: Deity
      }

Added

  • failRes for resolver failures
  • added kind: INPUT , OUTPUT
  • Automatic Type Inference (only for Object, Union and Enum)
  • More general stateful resolvers which accept instances of MonadIO (Authored by Sebastian Pulido [sebashack])
  • Utility to create web-socket applications with custom MonadIO instances (Authored by Sebastian Pulido [sebashack])
data Realm  =
    Sky
  | Sea
  | Underworld
    deriving (Generic, GQLType)

data Deity  = Deity{
    fullName:: Text,
    realm:: Realm
  } deriving (Generic, GQLType)

data Character  =
    CharacterDeity Deity -- Only <tyconName><conName> should generate direct link
  -- RECORDS
  | Creature { creatureName :: Text, creatureAge :: Int }
  --- Types
  | SomeDeity Deity
  | CharacterInt Int
  | SomeMutli Int Text
  --- ENUMS
  | Zeus
  | Cronus deriving (Generic, GQLType)

will generate schema:

enum Realm {
  Sky
  Sea
  Underworld
}

type Deity {
  fullName: String!
  realm: Realm!
}

union Character =
    Deity
  | Creature
  | SomeDeity
  | CharacterInt
  | SomeMutli
  | CharacterEnumObject

type Creature {
  creatureName: String!
  creatureAge: Int!
}

type SomeDeity {
  _0: Deity!
}

type CharacterInt {
  _0: Int!
}

type SomeMutli {
  _0: Int!
  _1: String!
}

# enum
type CharacterEnumObject {
  enum: CharacterEnum!
}

enum CharacterEnum {
  Zeus
  Cronus
}

rules:

  • haskell union type with only empty constructors (e.g Realm), will generate graphql enum

  • haskell record without union (e.g Deity), will generate graphql object

  • namespaced Unions: CharacterDeity where Character is TypeConstructor and Deity referenced object (not scalar) type: will be generate regular graphql Union

    union Character =
          Deity
        | ...
  • for union recrods (Creature { creatureName :: Text, creatureAge :: Int }) will be referenced in union type, plus type Creaturewill be added in schema.

    e.g

      union Character =
        ...
        | Creature
        | ...
    
      type Creature {
        creatureName : String!
        creatureAge: Int!
      }
    
    • all empty constructors in union will be summed in type <tyConName>Enum (e.g CharacterEnum), this enum will be wrapped in CharacterEnumObject and this type will be added to union Character. as in example above

    • there is only types left with form TypeName Type1 2Type ..(e.g SomeDeity Deity ,CharacterInt Int, SomeMutli Int Text),

      morpheus will generate objet type from it:

      type TypeName {
        _0: Type1!
        _1: Type2!
        ...
      }

Removed

  • removed kind: INPUT_UNION

Fixed

  • on filed resolver was displayed. unexhausted case exception of graphql error
  • support of signed numbers (e.g -4)
  • support of round floats (e.g 1.000)
  • validation checks undefined fields on inputObject
  • variables are supported inside input values

morpheus-graphql-0.7.1

26 Nov 18:43
85689f5
Compare
Choose a tag to compare
Pre-release
  • bounds supports megaparsec-8.0

morpheus-graphql-0.7.0

23 Nov 23:58
07dec73
Compare
Choose a tag to compare
Pre-release

Removed

  • toMorpheusHaskellAPi from Data.Morpheus.Document functionality will be migrated in morpheus-graphql-cli

Changed

  • liftM to MonadTrans instance method lift

  • liftEitherM to liftEither

  • Resolver operation m event value -> Resolver operation event m value , monad trans needs that last 2 type arguments are monad and value that why it was necessary

  • exposed Data.Morpheus.Types.Internal.AST

  • Mutation Resolver was changed from

resolver :: () -> ResolveM EVENT IO Address
resolver = MutResolver  {
  mutEvents = [someEventForSubscription],
  mutResolver = lift setDBAddress
}
-- Mutation Wit Event Triggering : sends events to subscription
resolver :: () -> ResolveM EVENT IO Address
resolver = MutResolver \$ do
  value <- lift setDBAddress
  pure ([someEventForSubscription], value)
-- or
-- Mutation Without Event Triggering
resolver :: () -> ResolveM EVENT IO Address
resolver _args = lift setDBAddress

Added

  • added parseDSL to Data.Morpheus.Document

  • GraphQL SDL support fully supports descriptions: onTypes, fields , args ...
    with (enums, inputObjects , union, object)
    for example :

    """
    Description for Type Address
    """
    type Address {
      """
      Description for Field city
      """
      city: String!
      street(
        """
        Description argument id
        """
        id: ID!
      ): Int!
    }
    GraphQL SDL
    type User {
      name: String! @deprecated(reason: "some reason")
    }

    will displayed in introspection

    introspection.json
    {
      "data": {
        "__type": {
          "fields": [
            {
              "name": "city",
              "isDeprecated": true,
              "deprecationReason": "test deprecation field with reason"
            }
          ]
        }
      }
    }
  • basic support of directive @deprecated on enumValue and object field, only on introspection

  • GraphQL Client deprecation warnings

    on type

    type Human {
      humanName: String!
      lifetime: Lifetime! @deprecated(reason: "some reason")
      profession: Profession
    }

    compiler output:

    warning:
      Morpheus Client Warning:
      {
        "message":"the field \"Human.lifetime\" is deprecated. some reason",
        "locations":[{"line":24,"column":15}]
      }
    
  • new helper resolver types aliases:

    • ResolveQ : for Query
    • ResolveM : for Mutation
    • ResolveS : for Subscription

    ResolveM EVENT IO Address is same as MutRes EVENT IO (Address (MutRes EVENT IO))

    is helpfull wenn you want to resolve GraphQL object

Fixed

  • added missing Monad instance for Mutation resolver
  • defineByIntrospectionFile does not breaks if schema contains interfaces
  • Morpheus Client supports Subscription and Mutationoperations

morpheus-graphql-0.6.2

02 Nov 06:57
95e2bd7
Compare
Choose a tag to compare
Pre-release

Added

  • support of ghc 8.8.1

morpheus-graphql-0.6.0

02 Nov 04:15
a63a6f5
Compare
Choose a tag to compare
Pre-release

Removed

  • removed morpheus cli for code generating, if you need cli you should use
    morpheus-graphql-cli

  • example API executable is removed from Production build

Added

  • helper functions: liftEitherM , liftM

      liftM :: m a -> Resolver o m e a
      liftEitherM :: m (Either String a) -> Resolver o m e a