morpheus-graphql icon indicating copy to clipboard operation
morpheus-graphql copied to clipboard

Alternative resolving for Subscription

Open nalchevanidze opened this issue 6 years ago • 7 comments

Specs

Variants

current

resolveNewUser :: ResolveS EVENT IO User
resolveNewUser = subscribe [USER] $ do 
    requireAuthorized
    pure subResolver 
  where subResolver (Event _ content) = liftEither (getDBUser content)

Problems

  • subscriptions can't be monad TODO:

alternative 1

resolveNewUser :: ResolveS EVENT IO User
resolveNewUser = lift $ do 
    requireAuthorized 
    pure resolver 
  where resolver event  
         | onUser event = Send liftEither (getDBUser event)
         | otherwise    = Ignore

data EVENT 
  = NewDog ID
  | NewCat ID

resolveNewDog:: ResolveS EVENT IO Dog
resolveNewDog = lift $ pure resolver 
  where  resolver (NewDog id) = Send $ lift (fetchDog id)
               resolver  _  = Ignore

resolveNewCat :: ResolveS EVENT IO Cat
resolveNewCat = lift $ pure resolver 
  where  resolver (NewCat id) = Send $ lift (fetchCat id)
               resolver  _  = Ignore

problem1: subscription can be monad. but this resolver never responses.

mixedNewCat :: ResolveS EVENT IO Cat
mixedNewCat = do 
   dog <- resolveNewDog
   resolveNewCat
  • on event NewCat resolveNewCat responses but not resolveNewDog.
  • on event NewDog resolveNewDog responses but not resolveNewCat.

alternative 2

add new field subscriptionChannels that maps to each subscription field corresponding channel

gqlRoot 
  = GQLRootResolver 
   { queryResolver
   , mutationResolver
   , subscriptionResolver
   , subscriptionChannels
   }

nalchevanidze avatar Apr 12 '20 23:04 nalchevanidze

So I just stumbled upon this. There's something I really don't understand in the current behavior of subscriptions, it's that it handle some sort of "state". How can I subscribe to the current time for instance ? It seems I can't do that if I don't create a mutation which is called to "fake" the change of time... I feel this is wrong and I think other servers use a more thread-oriented architecture but I'll try to find some examples.

Overall though there should be a way to subscribe to events outside of the morpheus-graphql server and serve them through a morpheus graphql subscription. I don't think the events (i.e. the EVENT type) should necessarily be part of the GraphQL schema as this is not its responsibility (perhaps the events come from outer space or it's an open set)

theobat avatar Apr 21 '20 17:04 theobat

Well actually I was wrong having a state and the events in the morpheus-graphql api is handy, but there should be another api for when you want more control on whether or not you send data to the client and when (that is not tied to any event in morpheus-graphql or mutation). I'm trying to figure it out.

theobat avatar Apr 22 '20 10:04 theobat

@theobat i seperated logic of store , websocketApp and httpApp. with this you can define your own store and websocket Server.

with publishEventWith:: Store event m -> event -> m () you can trigger events in store.

with httpAppWithEffect you can trigger publishEventWith or even send mutations events from current server node to another servers (e.g webhooks)

httpAppWithEffect :: (e -> m ())
  -> (Input 'Http -> Stream 'Http e m)
  -> a
  -> m a

you can review

https://github.com/morpheusgraphql/morpheus-graphql/pull/423/files

nalchevanidze avatar Apr 22 '20 21:04 nalchevanidze

Just wanted to say, this new architecture is great ! I managed to use rabbitMQ and postgres as external pubsubs.

theobat avatar Jun 10 '20 17:06 theobat

@theobat nice. would you please share an example for community?

nalchevanidze avatar Jun 12 '20 12:06 nalchevanidze

I'll try in the week end where do you think it's best to put it ? in the examples here ? or somewhere else (a dedicated repo ?) ?

theobat avatar Jun 12 '20 13:06 theobat

in best case create package examples-subscription-<your package name> here. so on every breaking change in library we are forced to update your examples too.

nalchevanidze avatar Jun 12 '20 14:06 nalchevanidze

outdated

nalchevanidze avatar Sep 28 '22 11:09 nalchevanidze