[Django]-Where to initialize a GraphQL Client inside Django App

1πŸ‘

βœ…

TLDR: instantiate new client right in the view method = new client for each request. (good option – overriding initial view method). Improve later.


It depends.

If there are no request / user options for the client (= client is the same for every request / user):

  1. import one from submodule as @ElPapi42 suggested (= same as instantiate new client in views.py globally, not as part of method logic)

  2. or instantiate new client right in the view method – new client for each request

If there are request / user specific options (i.e. client need to have request.user specific options / credentials):

  1. instantiate new client right in the view method

Option 1 – Client is instantiated once per worker view. Although it provides some performance benefits they are subtle and obscured:

  • you may not know what it means: shared client => possibly use methods that modify client state for different requests / users that rely on the state
  • worker lifetime is (should be) actually not that long
  • hard to assess performance benefits with hard to assess proper implementation

In reality you may want to connect to github with some current request.user specific options, perform multiple requests (= cookies may be involved and auto-added in subsequent requests => client cannot be shared with multiple users) = at least separate client for each user.

πŸ‘€Oleg Russkin

1πŸ‘

As per definition a graphql client needs it’s own configuration, modules and error handling I would suggest you to create a namespace adjacent to your other projects. Django uses the concept of Applications which is providing seperated configuration, logging and error handling for this case. You define additional Applications in your project in your settings.py in INSTALLED_APPS (Docs). Your project structure would then look smth like:

.
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md
β”œβ”€β”€ graphql-client
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ main.py
β”‚   β”œβ”€β”€ client.py
β”‚   β”œβ”€β”€ ressources
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ β”œβ”€β”€ repository.py
β”‚   β”‚   └── user.py
β”‚   β”œβ”€β”€ settings.py
β”‚   └── views.py
β”œβ”€β”€ api
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ admin.py
β”‚   β”œβ”€β”€ apps.py
β”‚   β”œβ”€β”€ migrations
β”‚   β”‚   └── __init__.py
β”‚   β”œβ”€β”€ models.py
β”‚   β”œβ”€β”€ tests.py
β”‚   β”œβ”€β”€ urls.py
β”‚   └── views.py
β”œβ”€β”€ db.sqlite3
β”œβ”€β”€ manage.py
β”œβ”€β”€ portfolio
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ asgi.py
β”‚   β”œβ”€β”€ settings.py
β”‚   β”œβ”€β”€ urls.py
β”‚   └── wsgi.py
β”œβ”€β”€ requirements.txt
└── setup.py

0πŸ‘

I ended up creating a python module in the /api Application called graphql.py that init the graphql client. from here, it is easily importable.

I decide not to create a separate Django Application for this because that will be overkill on this context, due to the simplicity of the code:

in graphql.py:

from gql import Client
from gql.transport.requests import RequestsHTTPTransport
from django.conf import settings

# Instaciate a graphql client
client = Client(
    transport=RequestsHTTPTransport(
        url='https://api.github.com/graphql',
        headers={'Authorization': 'bearer {token}'.format(token=settings.GITHUB_TOKEN)},
        verify=False,
        retries=3,
    ),
    fetch_schema_from_transport=True,
)
πŸ‘€ElPapi42

Leave a comment