apptension / saas-boilerplate

SaaS Boilerplate - Open Source and free SaaS stack that lets you build SaaS products faster in React, Django and AWS. Focus on essential business logic instead of coding repeatable features!

Home Page:https://apptension.com/saas-boilerplate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rewrite GraphQL Subscriptions to django-channels-graphql-ws

pziemkowski opened this issue · comments

Description

Current implementation of GraphQL subscriptions is very hacky and not scalable at all (even though that is the main reason for its hackiness).

Here's a breakdown of implementation:

  • AWS API Gateway is used as a connection backend for web sockets
  • AWS API Gateway runs Lambda functions when connection is established, lost, and message is received
  • Each message causes a request to our backend API, through regular load balancer to one of running AWS ECS tasks
  • GraphQL subscription query is written to DB
  • When an event that should cause execution of GraphQL query occurs all of matching GraphQL queries are executed in the very same AWS ECS task and dispatched back to the connected client, again through API Gateway.

Problems

  1. You can clearly see that even though we wanted to achieve scalability by moving web socket connections outside our AWS ECS we caused another, even harsher performance degradation – all GraphQL subscription execution run synchronously in the same ECS task (instance of the app).

  2. AWS API Gateway cannot be run on local machine, so we develop a very hacky solution – local ws server, which is a simulator of API Gateway + Lambda functions. That is very hard to maintain, as well as very hard to understand for other developers.

  3. Our implementation of query execution is quite crude and AFAIK doesn't support permission checks.

Describe the solution you'd like

My suggestion is to use django-channels-graphql-ws package which solves all of the problems above, but cames with some drawbacks:

  • we manage ws connections directly through Load Balancer on the ECS task with API Backend. Something that generally pushed us into the current solution.
  • we need to add Redis to our stack, but that is most likely happening anyway in near future for other features we have planned.

In my opinion though the advantages far outweigh the disadvantages.

https://github.com/datadvance/DjangoChannelsGraphqlWs

Describe alternatives you've considered

No response

Additional context

No response

Validations