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

Subscriptions RFC: Fetching initial state when subscribing #283

Closed
robzhu opened this issue Mar 6, 2017 · 13 comments
Closed

Subscriptions RFC: Fetching initial state when subscribing #283

robzhu opened this issue Mar 6, 2017 · 13 comments

Comments

@robzhu
Copy link
Contributor

robzhu commented Mar 6, 2017

Fetching initial state when subscribing.
@stubailo @rzachariah @romandvoskin @taion

Continuing the conversation from: #267 (comment)

@taion
Copy link

taion commented Mar 6, 2017

From my response on #267:

I think this is an application-level thing. "State" is not a concept that is inherent to GraphQL. Subscribing to e.g. streams of newly created items also doesn't necessarily admit an easy representation of current state. Imagine subscription updates that don't reflect idempotent operations – in such cases there isn't really a coherent initial state.

@stubailo
Copy link
Contributor

stubailo commented Mar 6, 2017

Agreed, there should be no concept of "initial state". If the backend implementation wants to send something back right away then it's free to do so, though.

@OlegIlyenko
Copy link
Contributor

I also agree with others, an initial state may or may not be present. I can imagine that some implementations may client decide what data to emit based on root field arguments (like lastSeenEventId or something along these lines)

@rmosolgo
Copy link

rmosolgo commented Mar 6, 2017

Oh, now I see how I could get an atomic subscription request:

subscription {
  commentCreated(postId: 4) {
    # `null` on first request, but present in later updates:
    comment { 
      body 
    }
    # present on first request, but `null` in later updates:
    initialPost {
      title,
      comments {
        body 
      }
    }
  }
}

Does that sound like it'd be within spec? The server may respond to a subscription operation with a response?

@taion
Copy link

taion commented Mar 7, 2017

@rmosolgo Exactly

@stubailo
Copy link
Contributor

stubailo commented Mar 7, 2017

Ooh! I really like that idea. Could be a clever way for the server to handle this kind of guarantee.

@robzhu
Copy link
Contributor Author

robzhu commented Mar 7, 2017

The server may respond to a subscription operation with a response?

Perhaps we can merge this with the "subscription active" response. Something like: "The server may respond to a subscription operation. This response can be useful for returning initial data or indicating whether the operation was successful."

@taion
Copy link

taion commented Mar 7, 2017

I'm not sure there's a need to merge those. Thinking about Relay for the moment, I might want the "subscription active" thing to be entirely delegated to my transport layer (really just a Socket.IO ack on my "subscribe" request), while the initial message should be exposed to e.g. the Relay network layer.

Maybe it's a bit of an implementation detail at that point.

You can imagine with something SSE-based that the "subscription active" bit could just be implicit, anyway.

@jamesgorman2
Copy link

This response can be useful for returning initial data or indicating whether the operation was successful.

as per @taion , (assuming 'operation was successful' refers to subscription active) you want to keep these on different layers. Any ACK messages could go in the graphql bytestream (ie bytes handed to graphql from the underlying transport layer) but not be part of the message stream. Extending what Jimmy said, this should be delegated to the transport layer until a reason to bring it into the graphql layer since most sane transport layers will give us enough for core subscribe and unsubscribe semantics.[1]

[1] it may be desirable to propagate error messages differently when they are graphql errors, eg bad upstream data.

@jamesgorman2
Copy link

@rmosolgo I'd imagine you would want to use a union to make this type safe and since you're muxing state and updates but only want one of each type per message.

type Comment {
  author: Person
  body: String
}
type Post {
  author: Person
  title: String
  body: String
  comments: Comment[]
}
subscription {
  postWithComments(postId: Int): Post | Comment
}

This now says 'I will always send you either a post or a comment'.

subscription {
  commentCreated(postId: 4) {
    # later responses
    ... on Comment { 
      body 
    }
    # the on first response
    ... on Post {
      title,
      comments {
        body 
      }
    }
  }
}

@stubailo
Copy link
Contributor

stubailo commented Mar 8, 2017

Yeah I definitely think the ACK should just be on the level of checking whether the connection is successful or not.

@robzhu
Copy link
Contributor Author

robzhu commented Mar 28, 2017

Sounds like there's consensus on this. Summarizing:

  • The server may respond to a subscription operation with a response.
  • "Subscription Active"/ACK is separate from the initial response.

@rmosolgo I like your wording for the requirement, would you please submit a PR? For example, at the end of this paragraph:

Subscribe: the Client initializes a subscription by sending a query and its variables to the server. When the Subscription is created, the input query and variables are mapped to a set of events to which the Subscription listens.

Within https://github.com/facebook/graphql/blob/master/rfcs/Subscriptions.md

@robzhu robzhu added the RFC label Mar 29, 2017
robzhu added a commit that referenced this issue Apr 28, 2017
When the client initializes a subscription, distinct from the "Subscription Active" acknowledgement, the server may also send an initial response. Typically, subscriptions depend on a combination of input variables and event data in order to "resolve". If a subscription is capable of returning an immediate response when a client subscribes, it may do so.
@robzhu
Copy link
Contributor Author

robzhu commented Apr 28, 2017

Updated the RFC: 48dac3f

@robzhu robzhu closed this as completed Apr 28, 2017
IvanGoncharov pushed a commit to IvanGoncharov/graphql that referenced this issue Jun 17, 2017
When the client initializes a subscription, distinct from the "Subscription Active" acknowledgement, the server may also send an initial response. Typically, subscriptions depend on a combination of input variables and event data in order to "resolve". If a subscription is capable of returning an immediate response when a client subscribes, it may do so.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants