Alternative resolving for Subscription
Specs
- [x] Subscription operations must have exactly one root field.
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
NewCatresolveNewCatresponses but notresolveNewDog. - on event
NewDogresolveNewDogresponses but notresolveNewCat.
alternative 2
add new field subscriptionChannels that maps to each subscription field corresponding channel
gqlRoot
= GQLRootResolver
{ queryResolver
, mutationResolver
, subscriptionResolver
, subscriptionChannels
}
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)
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 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
Just wanted to say, this new architecture is great ! I managed to use rabbitMQ and postgres as external pubsubs.
@theobat nice. would you please share an example for community?
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 ?) ?
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.
outdated