Skip to content
This repository has been archived by the owner on Nov 8, 2021. It is now read-only.

Improve DX for Query-based sync GraphQL #39

Open
pierre-moire opened this issue Feb 6, 2019 · 4 comments
Open

Improve DX for Query-based sync GraphQL #39

pierre-moire opened this issue Feb 6, 2019 · 4 comments

Comments

@pierre-moire
Copy link

GraphiQL is not showing available Query-based sync mutations (at least in Realm Cloud) and having to do a mutation in order to later get the results in a subscription is a huge pain.

Please can you create Query-based subscriptions on the fly when we start a GraphQL subscription ? You can probably for performance concerns de-duplicate them if needed and unsubscribe when the client closes ? This issue and #36 are currently my main issues to use GraphQL with a good level of maturity.

Note: you may have to mark those queries as created from GraphQL if you want to avoid edge cases when mixing with native client

@nirinchev
Copy link
Member

There are performance implications of such a design. Bootstrapping a partial Realm is not a cheap operation and neither is subscribing/unsubscribing, so it would be extremely wasteful to unsubscribe every time the client disconnects. The general guideline is to design your web app in a similar fashion as the native app, where you will check the existing Realm subscriptions and confirm if the one you need is already present. If it is, then you simply create a GraphQL subscription, otherwise, you create a Realm subscription followed by a GraphQL one. While it's tempting to combine both in a single API call,
it would:

  1. be semantically incorrect as executing a GraphQL query or subscription should not result in new data being added to the Realm
  2. likely result in performance degradation of the sync server due to subscription churn

It's possible that I'm missing something because I don't see any huge benefits. The way I imagine your code should look like is:

const subscriptions = await getRealmSubscriptions();
const query = "age > 18";
if (!subscriptions.find(s => s.name === "peopleScreen")) {
    await createRealmSubscription(query);
}

await subscribeForChanges(query);

So, yes, it adds some boilerplate, but you can easily write a helper function that does most of it and can be used in your various screens. I'll have to admin, I'm not a front-end developer, so it's possible that I'm overlooking some obvious improvement/use case and if that's the case, please let me know with some specific examples, but for the time being, it's unlikely we'll revisit this design.

@pierre-moire
Copy link
Author

Why it is working differently for the native clients then? When you subscribe to data in native, it indicates that you want to get matching elements from the reference database AND that you get the results as they change. You can probably remove the requirement of auto subscription removal if it has negative impacts.

Here in GraphQL every user will need to create subscriptions + create subscribe mutations.

Is it possible as a workaround to add the functionality of :

  • role-based query-sync subscriptions
  • global query-sync subscriptions
  • and make sure the mutations appear also in Realm Cloud (currently there is no way to do this ; the mutation createSubscription appears invalid)

Thanks for your feedback,

Regards,

Pierre

@pierre-moire
Copy link
Author

Just an update I could make the subscription mutation work with Realm Cloud also. It is just missing from GraphiQL (probably because we open it in full mode)

The 2 following points remain interesting for us :

  • role-based query-sync subscriptions
  • global query-sync subscriptions

@pierre-moire
Copy link
Author

pierre-moire commented Feb 7, 2019

You can probably add in the documentation that it is possible to nest elements as in any other GraphQL mutation, allowing (hopefully) a global subscribe of all related classes and that createXXXSubscription use the singular form of Classes name.

Example :

const EVENTS_SUBSCRIPTION = gql`
	mutation createEventSubscription {
		createEventSubscription {
			uuid
			name
			startAt
			endAt
			country {
				uuid
				name
			}

client
	.mutate({
		mutation: EVENTS_SUBSCRIPTION
	});

@nirinchev nirinchev removed their assignment Feb 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants