Skip to content

An example to show how to deploy GraphQL Subscriptions in Python on top of Django Graphene, Channels with simple JWT token authentication for queries, mutation, and subscriptions

License

Notifications You must be signed in to change notification settings

sprytnyk/deployment-of-gql-subscriptions-with-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deployment of GraphQL Subscriptions in Python (with auth)

It's an example of how to make more or less dockerised, production-ready GraphQL Subscriptions in Python on top of NGINX, Daphne, Supervisor that encompasses authentication process to GraphQL queries and mutations, the same about subscriptions itself, so your websocket connection will require a JWT token to be subscribed to something.

More sophisticated permissions checks can be done inside Django model signals, Python subscriptions (graphene-subscriptions), and Django Channels consumer.

Versions used in this example

  • Python 3.9.4

  • Redis 6.2.6

    If you use Redis below version 5 then you need to have inside requirements.txt channels-redis pinned to version 2.4.2 otherwise you will receive ERR unknown command 'BZPOPMIN'

  • PostgreSQL 14.0

  • Django 2.2.24 LTS

  • Nginx 1.21.3

  • Supervisor 3.3.5

Requirements

In order to interact with this example you need the fowolloing things:

Dive into example

Step 1

Assuming you installed all above requirements clone this repo and launch docker containers:

$ git clone https://github.com/sprytnyk/deployment-of-gql-subscriptions-with-auth.git
$ cd deployment-of-gql-subscriptions-with-auth
$ docker-compose up --build -d

After successful run of docker containers we need to obtain an access token:

$ curl \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "letmein"}' \
  http://localhost:8000/api/token/
# this will return something like this
{
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYzNDcyOTUzMywianRpIjoiODJkMTUyYzdiNjI0NGQwNzlhMTcwNTU0ZDI1MTI0MmQiLCJ1c2VyX2lkIjoxfQ.Gstb6RX4ga5yp9eosAPhRGJo1iNemGywvQYQqm7ZSjc",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjM0NjQzNDMzLCJqdGkiOiJlNGFiNjQyZDgyM2Q0NmNmYmE1YTRjZWNhNzAyNDhhNCIsInVzZXJfaWQiOjF9.g-qqbTJZ5HiCez8d_VgveMn4Z95oTLo9rtFev0aDWqA"
}
# you need only access token value

Open GraphQL Playground and type into the address bar http://localhost:8000/graphql/ and hit OPEN button.

Step 1

Step 2

Use the access token to make a GraphQL query like on the screenshot below, just update headers, provide the query, and hit play button. It should return hi back.

Query:

{
  hi
}

HTTP Headers:

{
  "Authorization": "Bearer your_access_token"
}

Step 2

If you provide an ivalid or wrong token it will throw a coressponding message: Wrong or invalid token

The same applies if you try to make GraphQL Subscription:

Subscription wrong token

Step 3

If you changed your valid token to see if it returns an error message make sure it's valid one because we're going to make our first subscription. This will wait for the update on Car model instance with a primary key 1.

Query:

subscription {
  carModelUpdated(pk: 1) {
    make
    model
  }
}

HTTP Headers (merged with connectionParams for websocket type of a connection by Apollo Client, see this):

{
  "Authorization": "Bearer your_access_token"
}

Step 3

Step 4

Then we need to go inside a docker container and lauch a script that will do an update to our model (picks randomly a make name). Navigate the root of the example and type such commands:

$ docker-compose exec web bash
$ python trigger_event.py

Step 4

This will show an update inside GraphQL Playground.

The first upate

Repeat step 4 and you will see another update inside GraphQL Playground.

The second update

This example may help you tie-up everything, so you can intergrate authentication for GraphQL queries, mutations, subscriptions, and deploy them.

Additional notes

Make sure your load balancers don't strip Connection and Upgrade headers and set reasonable timeouts for websockets (NGINX, Ingress, Gcloud, AWS), so they don't reconnect every 30 seconds or so.

About

An example to show how to deploy GraphQL Subscriptions in Python on top of Django Graphene, Channels with simple JWT token authentication for queries, mutation, and subscriptions

Topics

Resources

License

Stars

Watchers

Forks