GraphQL Subscriptions - Apollo Client Config (or websocket?)

Anyone willing to help me figure out why I can’t get a gql subcsription working?

I’m using the 8base Vue starter app. I’ve got normal queries and mutations working, no problem. I’ve tested my subscription query in 8Base GraphQL Explorer and it works great.

As far as I can tell its something in my Apollo Client config, specifically the api.js file in the utils directory. But I’m a little lost. I can’t seem to determine if its working at all. I sometimes see network errors. I can’t even see if a response is happening to troubleshoot enough. My knowledge of Apollo is limited. Sorry.

Also - I couldn’t find this anywhere in the docs or my 8base dashboard, but I found it searching around in their Slack group. The websocket endpoint is wss://ws.8base.com/ I’m still unclear if it requires a workspace id to be appended to that, or if its enough to include that in the header or token? I don’t know.

Here is a gist of the code.
[https://gist.github.com/nolawill/9ec158b6c1f2478ed3cfd8637d7d1ac5](http://8Base Vue Apollo Client Config Gist)

I have contacted 8Base support and they sent me the snippet in engineers_api_config.js and Ive tried that, but still with no success. I included the original starter api.js for comparison. My subscription query and the snippet from the component where I’m attempting to test this is also included.

Hoping I can get this working. My eventual use-case is a real-time list, but I’m just trying to succeed at a getting a basic subscription working with some “notes” example data so I can proceed to that. Any help is super appreciated. Thanks!

Hello @will!

You don’t need to append workspaceId to websocker uri. Headers shouldn’t affect Subscription link.

Can you describe the result of running subscription queries?

Hi @vorobeez !

Thats the thing - its hard to determine if its working right and I’m missing it because I don’t know where to look, or… if its just silently failing. Idk. Here’s one of the latest error messages I’ve been getting with the code I posted above in the git gist. Maybe its related. It does look like error output from the code snippet I was given.

log [Network error]: ServerParseError: "JSON.parse: unexpected end of data at line 1 column 1 of the JSON data" parseAndCheckHttpResponse bundle.esm.js:34

@will Everything looks fine with your example.

Here’s a working demo: https://codesandbox.io/s/festive-night-3we4q?fontsize=14&hidenavigation=1&theme=dark

I took code from engineers_api_config.js and just added little interaction to show subscription’s work.

Open to questions and ready to help :slight_smile:

I’m not sure about subscribeToMore parameter. There’s no such argument in subscribe function:


Wow. This is great. Thank you! Looks like I was missing a couple small pieces from your full code - like creating the apollo client after all the config.

subscribeToMore was something I found in Apollo’s documentation. I was just grasping at things that I thought might be missing for the results I wanted. Don’t assume it should have been there. If you say its not needed, and clearly it isn’t in your example, then I probably don’t need it. You ruled that out for me. Thank you.

I have full day, so I won’t be able to get back to this until later tonight (my time). But I will post my results here as soon as I do for everyone’s benefit. Thank you again for the help so far! Excited to see this working.

1 Like

I’m having similar trouble. I was able to mutate my 8base using a fork of the sandbox above

Update: I needed to specify “workspaceId” in the connectingPayload

And I can see the mutations in a subscription running in the 8base console, but I cannot seems to subscribe to it anywhere else, either in this sandbox or on my iOS client using Apollo, where I get

Error Domain=NSPOSIXErrorDomain Code=61 “Connection refused” UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}

I am able to configure it where I get

Apollo.WebSocketError.ErrorKind.unprocessedMessage("{“id”:null,“type”:“connection_error”,“payload”:{“code”:“ValidationError”,“message”:“The request is invalid.”,“details”:{“payload”:“Workspace id is required”}}}"))
WSError(type: Starscream.ErrorType.protocolError, message: “Connection Closed Normally”, code: 1000)

Which seems more promising but I can’t find or guess at the correct way to specify it.

Hi @mathieutozer! Did you specify access to read Users table for that api token?

It has administrator access - I now have a seemingly valid subscription that fires when User mutates but it sends an error message.

@mathieutozer

  1. Do not share publicly api token with administrator role. It can cause secure issues. Make separate role for that purpose with minimum possible access.
  2. What error does it send?

It’s a toy account so I was being intentionally careless - perhaps though my careless usage is causing this error!?

Here’s the error:

{“id”:“1”,“type”:“error”,“payload”:{“code”:“undefined”,“message”:“Something went wrong. Please contact support@8base.com.”,“details”:{“error”:“Something went wrong. Please contact support@8base.com.”}}}"

This is as raw a message coming from the socket as I can get on the client.

It only fires when I make a mutation, so the socket itself is working.

Here’s the update I promised. This took more effort than I hoped, but I learned some valuable things to share here.

First, @vorobeez the code demo you shared gave me an awesome head start and I managed to get subscriptions working, but my UI would not update. I couldn’t figure it out for days! I could see the output in my console, the network data even showed successful queries. Finally I decided to try vue-apollo since I was somewhat familiar with it, and that had subscribeToMore method that they recommend for “smart” subscriptions. Still wouldn’t work.

Here are a few links on this information for reference:

The Solution (for me anyway)

FINALLY, I figured out that its a client caching issue. Basically, what you return to the cache via the subscribeToMore method has to match exactly what was there before either in structure or by ID. This is extremely poorly documented pretty much everywhere I searched. Or maybe I just didn’t get it. Idk. Even all the tutorials glaze over this point. Maybe this is a bad case of “assumed knowledge” but no one explicitly covers that specific point. Whether you use the subscribe method, like your example code with the next function, or the subscribeToMore method like what I wanted to do - you have to do the work of parsing the updated data from the previous data and then doing what you want with it. If you do not use an id, or keep the same data structure as the query that you want to update, it will fail. The object or array you return to the client cache has to match for it to “smartly” update the UI, otherwise it assumes its not the same and does nothing with it. This is not clearly explained in the documentation. Their examples basically have a code comment that says “return your data here” and that’s it. No one seems to talk about that fact that you have to do some leg work at that point to get the data updates into the components or UI that you want.

Once I matched up my return data structure to the what the cache expects, and I handled my CRUD use-cases, everything worked beautifully!

I’ve updated my example code that I was struggling with before to show what is now working for me. I am finally unblocked by this and have fully working subscriptions! :raised_hands: :smile:

Here’s a quick demo gif to see my subscription working.
I interact with the UI in one client/browser, and you can see the changes in a separate browser also using a subscription. :clap: :clap: :clap:

@mathieutozer Not sure if any of my progress will help you specifically. Looks like its possibly a different issue for you, but maybe some of the same concepts will apply for using apollo client in iOS. Hope you make more progress soon. Please share if you do, or maybe open a separate topic specifically for that and share there. (tag me if you do please!) All the best.

1 Like

I reviewed your example. It’s seems that you fixed the error. Mutation and subscription work. The only issue is data access. You need to write data.data.Users.node.id instead of data.data.User.node.id.

Can you tell what was wrong with the code?

I glad you made it :slight_smile: Thank you for the deep explanation of the problem!

If you would have another issue with apollo, please write to our community.

1 Like

I see, yes that was it. This means that my problem must be with my Apollo / websocket configuration on the iOS side.