morpheus-graphql
morpheus-graphql copied to clipboard
Morpheus Client Supports Subscription Stream
rough idea, how it should work
we will use wuss
if it will work with custom monad:
newtype ClientStream m a = ClientStream {
unClientStream :: (Either String a) -> m ()
}
else
newtype ClientStream a = ClientStream {
unClientStream :: (Either String a) -> IO ()
}
and it can be used with:
subscribe :: (Monad m, FromJSON a) => (ByteString -> m ByteString) -> Args a -> ClientStream m a
I was going to have a go at this, but where should I look for the corresponding example of how query is implemented?
I see there is some work started in examples/Subscription/SimpleSubscription.hs
is this a good place to start?
Ah no, I see that's for server definitions.
i did not understand. do you want to implement this feature? i mean make a PR for it?
Hi @nalchevanidze yes, I'd like to try implementing the feature. Just trying to get advice on where I should start looking.
https://github.com/morpheusgraphql/morpheus-graphql/blob/ed75bfdaaea017cc8004f351ebd043c6576e9abf/src/Data/Morpheus/Execution/Client/Fetch.hs#L42-L48
so i would extract this function to 2 parts
class Fetch a where
buildRequest :: Proxy a -> Args a -> GQLRequest
buildResponse: : ByteString -> m (Either String a)
they can be used in fetch
and subscribe
where subscribe
subscribe ::
Args a
-> ( Either String a -> IO () ) -- callback
-> ClientApp ()
subscribe args callback connection = do
-- send initial GQL Request
sendTextData connection request
-- handle GQL Subscription responses
void . forkIO . forever $ do
message <- receiveData connection
value <- buildResponse message
callback value
where
request = encode (buildRequest (Proxy @a) args)
main :: IO ()
main = runSecureClient "<api url>" 443 "/" (subscribe (SomeArgs {}) callback)
I'm not familiar with wuss.
@sordina you may need to read its documentation, i just took an example code and modified for my purpose. it may not work but demonstrates idea behind it (i hope).
great thank you for contributing :)
if you come up in the development process with better idea, you can freely go for it
@sordina do you need some help?
Hi @nalchevanidze yes, I've gotten a bit stuck with the approach. I'm adding a test/example to begin with and getting a bit of a cryptic error relating to lookupFieldType, not sure the root of the issue. I've been a bit busy to sit down and figure it out yet, but if you're on the slack group maybe we could discuss? Otherwise happy to keep the thread open here!
examples/Client/Client2.hs:20:1: error:
[{"message":"Unhandled Compile Time Error: \"newFoo - during lookupFieldType OutputObject\" ;","locations":[]}]
I'm not sure if this is due to missing implementation around subscription
or if the introspection.json needs further additions. The buildInputType
function seems to be involved but is a bit complicated to unpack easily.
I'm trying to write a "test" like the following:
defineByIntrospectionFile
"./assets/introspection.json"
[gql|
subscription MySubscription
{
newFoo
{ email }
}
|]
Maybe I'll create a WIP PR so that it's easier to share what I'm up to.
@nalchevanidze created one here: https://github.com/morpheusgraphql/morpheus-graphql/pull/301
looks like some of the better compileError
messages that I'd put together to track down the issue just got done by someone else, so my work so far is even smaller!
@nalchevanidze ah awesome looks like the bug relating to the issue stopping my test from compiling was fixed!
Hi @nalchevanidze I'm having another go at this. Perhaps we could pair up some time? I'm stuck as usual ahah!
Sure. What is your approach?
will be available in next version