-
Notifications
You must be signed in to change notification settings - Fork 133
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
Using grapqhl-subscriptions with serverless backend #53
Comments
You must have a continuously running server to manage websocket connections. AWS Lambda can handle regular HTTP requests since they're short-lived. Websockets are by definition long-lived. Edit: It might be possible to run a lambda instance during the lifetime of the websocket, but I can't imagine this would be worthwhile. |
Given that there are Redis and MQQT subscription packages http://dev.apollodata.com/tools/graphql-subscriptions/external-pubsub.html, are there any tutorials or efforts to create tutorials surrounding the use of managed pubsub services like AWS SNS or GCP PubSub? Furthermore, as someone using Firebase DB as the storage layer of my GraphQL, is there a way to leverage the real-time part of FirebaseDB through GraphQL on the client? I am exploring these myself, but curious if others had already attempted this and what the outcome was. |
Could you use AWS IoT websockets in front of lambda? |
@jthegedus Any luck so far? |
@mattfysh I haven't looked at the AWS IoT websockets service myself. I've used AWS more than GCP but found that GCP PubSub is more generic and therefore easier to understand how it fits into the subscription model. @scf4 There's a lot of flux with how subscriptions are managed since the finalization of the subscription RFC in the GraphQL spec. I'm trying to keep up with all the changes in the various repos - subscriptions-transport-ws, graphql-js, graphql-subscriptions - to see where exactly the subscriptions state is kept and where a managed pusub service fits. It seems that it should be easier, but the changes are still in progress and there's no point working with the previous implementation as the version built against the spec will be the gold standard implementation. |
I am not sure this issue has a simple solution. |
Surely by its very nature, AWS Lambda deals with short lived connections. Websockets aren't short lived. So perhaps AWS Lambda could deal with all the queries and mutations, and an intelligent Application Load Balancer that routes websockets to a single EC2 instance? |
The solution I am thinking of for this problem isn't trying to get websockets to work in ephemeral compute services (Lambda/Cloud Functions/Azure Functions), it's to move the logic of the connection state to a managed service. A non-websocket pubsub system that enables server to client push of data is what is required. So far from my research, the options from the big 3 include: Azure: Event Hub or Service Hub The difference with using one of these services to a WS implementation is that the services generally only do server->client data push, so requests to subscribe/unsubscribe and the rest of your GraphQL queries & mutations etc still need to be through a HTTP GraphQL server - personally I like this unidirectional flow of data anyway. Recently in the GraphQL Radio podcast, ep3 Microsoft guest Erik Schlegel outlined how they are using Azure Event Hub as the data transport for their GraphQL subscriptions - https://youtu.be/crXSN8SKjGI?t=14m58s It is also mentioned that they may be open-sourcing their Azure Event Hub / PubSub Engine wrapper at a later date. Another issue with this type of system is that the message payload sizes are then dictated by the service being used, which vary from vendor to vendor. GCP Firebase Cloud Messaging is what I am working on atm as I use GCP more than AWS. |
@jthegedus ahh, I see where you're going with this now. So basically someone just needs to write a subscription transport-layer for SNS/FCM/Event Hub (or all three) and then use that for the subscription updates. Interesting! If only I had a bit more time spare I'd take a look myself... maybe in a few weeks. |
@Siyfion Precisely, I just happened to start looking into this when significant changes were being made. I'm now just waiting for this to be merged #78 which I think is the last significant change of the subscription related layer at this time. I'm going to work on the FCM transport layer, I believe some Microsoft developers will publish the Event Hub implementation sometime in the near future. As for AWS I'm not as proficient there, so maybe someone else can tackle that package. |
@jthegedus Awesome, it almost sounds like a plan taking shape! lol. As for the AWS-side, I would imagine it's probably the more commonly used cloud provider, so I'm sure there will be some people around that are happy to help, maybe even some of the MDG guys that helped implement the Galaxy hosting solution, I imagine they are pretty familiar with the AWS stack..? |
Some resources I've found regarding possible implementations using AWS. These don't use GraphQL, but show how a messaging service can be created on AWS services: AWS IOT: https://serverless.com/blog/serverless-notifications-on-aws/ @mattfysh The interesting thing about a serverless backend is that it changes which problems need solving. Instead of scaling connection etc you need to consider the limitations of the individual services. Eg: payload size, payload TTL, delivery guarantees (at least once and dealing with duplicate deliveries), upstream messaging etc |
I have this working in AWS using the demo from medium. Once I have in incorporated into the project it was poc'd for I'll try and write it up here, but in the meantime: You can't use SNS as it is not a traditional pubsub broker. Have to implement using graphql-mqtt-subscriptions, AWS IOT & the aws iot js sdk |
@jonmanzo : Hi!, can you share the demo link from medium? :p |
@giautm Here you go, but bear in mind it is a little bit out of date due to Client: https://dev-blog.apollodata.com/tutorial-graphql-subscriptions-client-side-40e185e4be76 |
I just published an initial version of a ws transport client and a server package that works with AWS iot and lambda. AWS IoT is used for socket connections and a db is used to store subscription state. |
Just so everyone here is aware, AWS just launched Serverless GraphQL as a Service called AWS AppSync - https://aws.amazon.com/blogs/aws/introducing-amazon-appsync/ and the docs http://docs.aws.amazon.com/appsync/latest/devguide/system-overview-and-architecture.html This service offers:
They also have a client SDK - https://github.com/awslabs/aws-mobile-appsync-sdk-js - which is built by extending ApolloClient2.0 where offline support, auth and all the network layer are simple apollo-links. Go read the source, it's super cool stuff. No idea at the moment on whether you can extend the AppSync GraphQL server instances with stuff like ApolloEngine. fingers crossed |
@gnanda17 Thank you for posting AWS IoT example. to everyone:
It'd be great to see an example of GraphQL subscriptions with AWS SNS or Google Pub/Sub. |
@OlzhasAlexandrov When initially looking into this I found that GCP Pub/Sub isn't able to push to device endpoints; at least that was my understanding. https://cloud.google.com/pubsub/docs/push#configuring-http-endpoints
I didn't invest any further time and actually test an implementation to see if this was the case. I am still working on an FCM based transport, but it's delayed a bit due to changing implementation lang. |
@jthegedus @OlzhasAlexandrov very cool insights!
|
Closing this issue because it is unclear if the topics being discussed are actually in scope for this project. |
Related issue in apollo-server repo: apollographql/apollo-server#2129 |
hey @jthegedus did you ever make any progress on that? we currently already have fcm in our project for web-push notifications and using the same as a replacement for websockets sound intrigueing. |
@boredland I gave up on building an FCM transport for GraphQL. These are the results of my investigation (though I am certainly incorrect in some places, corrections welcome):
The FCM design would also require heavy client-side integration. It would need to capture the FCM data message and perform a merge of the result into the local GraphQL cache. I couldn't figure an easy way that didn't require lock-in to the Apollo ecosystem / include other graphql clients. Given this library doesn't offer the configuration I would desire, I gave up instead of trying to build my own GraphQL server module. The ideal design here would be:
Advantages:
Disadvantages:
Other notes:
For my recent thoughts on GraphQL subscriptions, see this thread on the request to add subscriptions to the popular Having said that though, if GraphQL subs over FCM existed I would use it in a heartbeat over websockets or polling. @boredland I'm happy to collaborate/contribute should you go down this path. I think I gave up to soon and now am not heavily involved in GraphQL daily. |
folks, I’m releasing a serverless specialised graphql framework with support for subscriptions on AWS (later GCP and Azure) https://github.com/kraken-js/kraken-js we developed this framework internally and it runs in production already and now we are open sourcing it, it’s still pending documentation and samples to facilitate the life of newcomers but while that is not available feel free to reach out to me if you want to use it and have questions, any feedback is welcome. |
Has anyone tried using a 3rd party service like Pusher or Pubnub to manage the websocket connection for GraphQL subscriptions? For example, use a short lived HTTP connection like AWS Lambda for queries and mutations, but a different service like Pusher (which uses Redis behind the scenes, I believe) for long lived web sockets connections that pushes the subscriptions out to clients? |
@johnnyoshika I looked into Pusher but it has the same issues as FCM does that I outline above. From the existing GraphQL subscription libraries I am aware of, you are only given an interface for configuring message propagation between the servers that front the API, the server-client connection is always considered websockets and the server environment (for subscriptions) is always considered stateful. |
@jthegedus That makes sense. So far the only service that I found to support Subscriptions (via websockets) out-of-the-box is Heroku. Even then, Heroku's web socket connection times out every 55 seconds (https://devcenter.heroku.com/articles/websockets#timeouts). Apollo Client is pretty good about re-establishing the connection right away, so that doesn't seem to be a problem. |
@jthegedus / @johnnyoshika Have you tried Ably? We've got an NPM module for GraphQL (https://www.npmjs.com/package/graphql-ably-pubsub) and do all of the reconnection magic you could want. |
Hey @Ugbot you guys should definitely add it here: https://github.com/apollographql/graphql-subscriptions#pubsub-implementations to help with discoverability ;) |
We are trying but they are not accepting the PR 🙁 |
@Ugbot It looks really good. So can we continue to use AWS (e..g AWS Lambda) for our GraphQL queries and mutations, but then point the client (e.g. Apollo Client) to Aply for just GraphQL subscriptions? For example, I'd be doing something like this with Apollo Client:
|
How can we use graphql-subscriptions with a serverless backend like AWS Lambda? In this case, transport using web sockets won't work since a lambda function can't run for long time.
The text was updated successfully, but these errors were encountered: