Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are subscriptions limited to being top level? #908

Open
jerel opened this issue Apr 2, 2021 · 3 comments
Open

Are subscriptions limited to being top level? #908

jerel opened this issue Apr 2, 2021 · 3 comments
Labels
area::subscriptions Related to GraphQL subscriptions discussion

Comments

@jerel
Copy link
Contributor

jerel commented Apr 2, 2021

I think this is a bug but I'm not sure... I've spent several days reading code and trying in vain to achieve this so I'd like a second opinion.

Queries can be set up like this (and so can mutations):

pub struct QueryRoot;

#[juniper::graphql_object(Context = Context)]
impl QueryRoot {
  fn settings(&self) -> settings::SettingQueries {
    settings::SettingQueries
  }
  fn other(&self) -> other::OtherQueries {
    other::OtherQueries
  }
}

However, no variation of this seems to be possible with Subscriptions (this doesn't compile):

pub struct SubscriptionRoot;

#[juniper::graphql_subscription(Context = Context)]
impl SubscriptionRoot {
  fn settings(&self) -> settings::SettingSubscriptions {
    settings::SettingSubscriptions
  }
  fn other(&self) -> other::OtherSubscriptions {
    other::OtherSubscriptions
  }
}

Shouldn't this work or is it a design decision? Are all subscriptions for the whole app required to be in one root impl?

@LegNeato
Copy link
Member

LegNeato commented Apr 4, 2021

What is the compilation error you are getting? I didn't work on the subscriptions work but might be able to answer the question.

@LegNeato LegNeato added the area::subscriptions Related to GraphQL subscriptions label Apr 4, 2021
@jerel
Copy link
Contributor Author

jerel commented Apr 5, 2021

Thanks @LegNeato, I should have added all this to the original issue. I'll show a couple of the angles that I've tried and their errors:

// this is identical to my usage of the Query/Mutation API but with s/graphql_object/graphql_subscription/ and async fns
pub struct SubscriptionRoot;

#[juniper::graphql_subscription(Context = Context)]
impl SubscriptionRoot {
  async fn settings(&self) -> settings::SettingSubscriptions {
    settings::SettingSubscriptions
  }
  async fn other(&self) -> other::OtherSubscriptions {
    other::OtherSubscriptions
  }
}

pub struct SettingSubscriptions;
#[juniper::graphql_subscription(Context = Context)]
impl SettingSubscriptions {
  pub async fn settings() ...
}

gives this error at the SubscriptionRoot site:

#[juniper::graphql_subscription(Context = Context)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `futures::Stream` is not implemented for SettingSubscriptions

So I thought "maybe we can define the top level as a graphql_object which then pulls in the graphql_subscription":

pub struct SubscriptionRoot;

#[juniper::graphql_object(Context = Context)]
impl SubscriptionRoot {
  fn settings(&self) -> settings::SettingSubscriptions {
    settings::SettingSubscriptions
  }
  fn other(&self) -> other::OtherSubscriptions {
    other::OtherSubscriptions
  }
}

pub struct SettingSubscriptions;
#[juniper::graphql_subscription(Context = Context)]
impl SettingSubscriptions {
  pub async fn settings() ...
}

gives this error at the SubscriptionRoot site:

#[juniper::graphql_object(Context = Context)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `GraphQLValueAsync<__S>` is not implemented for SettingSubscriptions

Which is understandable I suppose because we're defining SubscriptionRoot as a graphql_object. I thought perhaps this was a way that could work today in userland code but I wasn't able to get GraphQLValueAsync<__S> defined correctly for some reason.

@tyranron
Copy link
Member

@jerel as far as I recall, this is not supported at the moment. The reason is that is not clear how such situations should be resolved. A subscription in a nutshell is a Stream. So having a Stream, whcih field resolves to another Stream, how you expect to behave this on client?

Do you have any reference examples how it's handled in other languages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area::subscriptions Related to GraphQL subscriptions discussion
Projects
None yet
Development

No branches or pull requests

3 participants