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

Morpheus Client Supports Subscription Stream

Open nalchevanidze opened this issue 5 years ago • 15 comments

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

nalchevanidze avatar Oct 22 '19 16:10 nalchevanidze

I was going to have a go at this, but where should I look for the corresponding example of how query is implemented?

sordina avatar Nov 01 '19 04:11 sordina

I see there is some work started in examples/Subscription/SimpleSubscription.hs is this a good place to start?

sordina avatar Nov 01 '19 04:11 sordina

Ah no, I see that's for server definitions.

sordina avatar Nov 01 '19 04:11 sordina

i did not understand. do you want to implement this feature? i mean make a PR for it?

nalchevanidze avatar Nov 02 '19 16:11 nalchevanidze

Hi @nalchevanidze yes, I'd like to try implementing the feature. Just trying to get advice on where I should start looking.

sordina avatar Nov 03 '19 04:11 sordina

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 :)

nalchevanidze avatar Nov 03 '19 13:11 nalchevanidze

if you come up in the development process with better idea, you can freely go for it

nalchevanidze avatar Nov 03 '19 13:11 nalchevanidze

@sordina do you need some help?

nalchevanidze avatar Nov 09 '19 01:11 nalchevanidze

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":[]}]

sordina avatar Nov 09 '19 02:11 sordina

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 }
    }
  |]

sordina avatar Nov 09 '19 02:11 sordina

Maybe I'll create a WIP PR so that it's easier to share what I'm up to.

sordina avatar Nov 09 '19 02:11 sordina

@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!

sordina avatar Nov 09 '19 02:11 sordina

@nalchevanidze ah awesome looks like the bug relating to the issue stopping my test from compiling was fixed!

sordina avatar Nov 10 '19 11:11 sordina

Hi @nalchevanidze I'm having another go at this. Perhaps we could pair up some time? I'm stuck as usual ahah!

sordina avatar Apr 09 '20 05:04 sordina

Sure. What is your approach?

nalchevanidze avatar Apr 09 '20 12:04 nalchevanidze

will be available in next version

nalchevanidze avatar Aug 31 '22 20:08 nalchevanidze