Skip to content

feat: implement GraphQL over WebSocket Protocol - #686

Closed
amondnet wants to merge 11 commits into
Netflix:masterfrom
amondnet:grapqhl-transport-ws
Closed

feat: implement GraphQL over WebSocket Protocol#686
amondnet wants to merge 11 commits into
Netflix:masterfrom
amondnet:grapqhl-transport-ws

Conversation

@amondnet

@amondnet amondnet commented Oct 8, 2021

Copy link
Copy Markdown
Contributor

Pull request checklist

  • Please read our contributor guide
  • Consider creating a discussion on the discussion forum
    first
  • Make sure the PR doesn't introduce backward compatibility issues
  • Make sure to have sufficient test cases

Pull Request type

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Other (please describe):

Changes in this PR

Describe the new behavior from this PR, and why it's needed
Issue #684

Alternatives considered

Describe alternative implementation you have considered

@amondnet
amondnet force-pushed the grapqhl-transport-ws branch from 348cd13 to 125b065 Compare October 8, 2021 06:06
@srinivasankavitha

Copy link
Copy Markdown
Contributor

Thanks for the PR @amondnet. We will test out the changes. My initial thought is that we need a better name for the module as it can be confusing with the existing websockets implementation that we already support. Having multiple websocket protocols can be very confusing for the user.

@paulbakker paulbakker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting the conversation about this! If this is the protocol that most folks use, we should obviously support that.

A few things we need to think about and/or test for:

  • Can this be used together with the existing implementation? E.g. can both modules be active at the same time? It does look like it, because the new module is registering on /graphql.
  • Both WebMVC and Webflux should be supported
  • Does this conflict with "normal" queries since it's on /graphql? (I think this should work, but we need to make sure).
  • This should be supported by the GraphQL client as well that was recently added.
  • Does this impact the Graphiql setup we have?

package com.netflix.graphql.dgs.transports.websockets

const val GRAPHQL_TRANSPORT_WS_PROTOCOL = "graphql-transport-ws" // graphql-ws subprotocol
const val GRAPHQL_SUBSCRIPTIONS_WS_PROTOCOL = "graphql-ws" // subscriptions-transport-ws subprotocol

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not actually supported by the new module right? It's what the existing websocket implementation does.

Comment thread settings.gradle.kts Outdated
include("graphql-dgs-pagination")
include("graphql-dgs-subscription-types")
include("graphql-dgs-transports-websockets")
include("graphql-dgs-transports-websockets-autoconfigure")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this webflux specific? Can it be used with the webmvc starter as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulbakker It can be used with webmvc and webflux.

@amondnet

Copy link
Copy Markdown
Contributor Author

@srinivasankavitha

My initial thought is that we need a better name for the module as it can be confusing with the existing websockets implementation that we already support. Having multiple websocket protocols can be very confusing for the user.

Yes, I agree. Actually I'm not sure how to name the module. graphql-dgs-subscriptions-websockets and graphql-dgs-subscriptions-sse support only Subscriptions.
GraphQL over WebSockets and GraphQL over SSE support all 3 GraphQL operations:Queries, Mutations, Subscriptions. These protocols aims to be standardised and become a part of GraphQL with the help of the foundation’s GraphQL over HTTP work group.

graphql/graphql-over-http#140
graphql/graphql-over-http#163

@srinivasankavitha

srinivasankavitha commented Oct 11, 2021 via email

Copy link
Copy Markdown
Contributor

@srinivasankavitha

srinivasankavitha commented Oct 11, 2021 via email

Copy link
Copy Markdown
Contributor

)
}
is Message.PongMessage -> {
// TODO: onPong

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing to do here, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srinivasankavitha According to the spec, it should call the onPong event handler if exists.

if (session.isOpen) {
session.sendMessage(jsonMessage)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to cleanup the context for this subscription id from the session upon error?
contexts[session.id]?.subscriptions?.remove(id)

@srinivasankavitha

Copy link
Copy Markdown
Contributor

What set up are you using for the client to test the server? Are you using Apollo client with graphql-ws library?

@srinivasankavitha

Copy link
Copy Markdown
Contributor

@amondnet - when you get a chance, could you describe your set up that you used to test this? Do you have an apollo client set up with the graphql-ws library or do you have your own client? If you have any client code that you can share, much appreciated.

@amondnet

Copy link
Copy Markdown
Contributor Author

@srinivasankavitha This weekend I will share testable code.

@srinivasankavitha

srinivasankavitha commented Jan 25, 2022

Copy link
Copy Markdown
Contributor

@amondnet - thanks for adding the test and that looks good. The PR overall looks good to me. I tried to test this with a real client with the DGS based on the docs here: https://github.com/enisdenjo/graphql-ws#use-the-client but it does not seem to work after enabling the new module. Have you been able to set up a client to test this end to end? Could you share what you have, if so? Thanks!
For reference, I am trying to set this up with the example app and ui that is part of the dgs framework repo here: https://github.com/Netflix/dgs-framework/tree/master/graphql-dgs-example-shared

@michaelboyles

Copy link
Copy Markdown

Happy to test my (closed source) application with an Apollo client if you like. Is there any config necessary on the DGS side, or does the client negotiate the subprotocol as part of the handshake or something?

@srinivasankavitha

Copy link
Copy Markdown
Contributor

Happy to test my (closed source) application with an Apollo client if you like. Is there any config necessary on the DGS side, or does the client negotiate the subprotocol as part of the handshake or something?

That would be really helpful! Unfortunately, the testing will involve cloning and building the forked repo with the changes and publishing a local snapshot that you can use in your DGS app. You will also need to add the new module implementation(project(":graphql-dgs-transports-websockets")) in your DGS app to get this functionality.

@amondnet

Copy link
Copy Markdown
Contributor Author

@paulbakker

Can this be used together with the existing implementation? E.g. can both modules be active at the same time? It does look like it, because the new module is registering on /graphql.

Yes, we can use together. Websocket uses http only during handshake.
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake

Both WebMVC and Webflux should be supported

Ok. I will add both.

Does this conflict with "normal" queries since it's on /graphql? (I think this should work, but we need to make sure).

No conflict.

@amondnet
amondnet force-pushed the grapqhl-transport-ws branch from 07d7587 to 3fcc7c9 Compare April 13, 2022 18:14
@amondnet
amondnet force-pushed the grapqhl-transport-ws branch from 495243c to 8a129cc Compare April 20, 2022 09:26
@michaelboyles

Copy link
Copy Markdown

Sorry for the delay. I'm still happy to test this if it will help push it through. Unfortunately it's not currently building because of linter errors.

@srinivasankavitha

Copy link
Copy Markdown
Contributor

@michaelboyles - I am now able to test this with Apollo client and have some fixes. Will push those in the next day. I will be doing some more testing and likely get this PR merged after next week. Will post updates here. Apologies again for the delay due to conflicting internal priorities.

@srinivasankavitha

Copy link
Copy Markdown
Contributor

@amondnet - could you please give me access to push a branch to your fork? I have some fixes based on testing your PR.

@amondnet

amondnet commented Aug 1, 2022

Copy link
Copy Markdown
Contributor Author

@srinivasankavitha I have invited you as a collaborator.

@srinivasankavitha srinivasankavitha mentioned this pull request Aug 8, 2022
5 tasks
@amondnet

Copy link
Copy Markdown
Contributor Author

@srinivasankavitha

Copy link
Copy Markdown
Contributor

Merged this PR with additional fixes, implementation for webflux and some refactoring: #1200.

I'll close this one out. Thanks @amondnet for all the contributions for this feature.

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

Successfully merging this pull request may close these issues.

4 participants