Skip to content

Project and applications

To help you modularize your API, Turbulette allows you to split your project into reusable applications, very similar to what Django does.

Project

Basically, a Turbulette project is a composition of applications, each one having its own GraphQL schema, resolvers, database models etc. Like in Django, they can be "toggled" using the INSTALLED_APPS settings:

INSTALLED_APPS=myproject.app_1,myproject.app_2
from starlette.datastructures import CommaSeparatedStrings

...

INSTALLED_APPS = config("INSTALLED_APPS", cast=CommaSeparatedStrings, default=[])

To create a project, use the built-in turb CLI:

$ turb project --name eshop

You should get with something like this :

.
└── 📁 eshop
    ├── 📁 alembic
    │   ├── 📄 env.py
    │   └── 📄 script.py.mako
    ├── 📄 .env
    ├── 📄 alembic.ini
    ├── 📄 app.py
    └── 📄 settings.py

Let's break down the structure :

  • 📁 eshop

    Here is the so-called Turbulette project folder, it will contain applications and project-level configuration files

  • 📁 alembic

    Contains the Alembic scripts used when generating/applying DB migrations:

    • 📄 env.py

      This module is the entrypoint used by Alembic to manage database migrations. In most cases, you don't need to edit this file, you just want it to stay in the alembic folder.

    • 📄 script.py.mako

      The template used by alembic to generate migrations. I you open it, you will see the Python code that generates a migration. When Alembic creates it, it will just replace tags with actual values.

  • 📄 .env

    The actual project settings live here

  • 📄 app.py

    Your API entrypoint, it defines the ASGI app where the server must point.

  • 📄 settings.py

    The project settings module, see settings

Question

Why have both .env and settings.py?

You don't have to. You can also put all your settings in settings.py. But Turbulette encourage you to follow the twelve-factor methodology, that recommend to separate settings from code because config varies substantially across deploys, code does not. This way, you can untrack .env from version control and only keep tracking settings.py, which will load settings from .env using Starlette's Config object.

At this stage your API is not functional. To start coding, you need to create an application.

Application

Run this command under the project directory (eshop) :

$ turb app -n account

Info

You need to run turb app under the project directory because the CLI needs to access the almebic.ini file to create the initial database migration.

You should see your new application under the project folder :

.
└── 📁 eshop
    ...
    |
    └── 📁 account
        ├── 📁 graphql
        ├── 📁 migrations
        │   └── 📄 20200926_1508_auto_ef7704f9741f_initial.py
        ├── 📁 resolvers
        └── 📄 models.py

Details :

  • 📁 graphql

    All the GraphQL schema exposed by the account application will live here.

    Only GraphQL files should be placed here, to clearly separate logic from the schema. By grouping your schema in a dedicated folder, you get an instant view of a specific part of your API's functionalities that is even understandable by non-technical folks.

  • 📁 migrations

    Contains database migrations generated by Alembic (or manually).

  • 📁 resolvers

    Python package where you will write GraphQL resolvers.

    On server startup, Turbulette will import GraphQL schema and resolvers defined by all installed applications and will ask Ariadne to bind resolvers to the schema. Ariadne uses decorators to bind resolvers functions, and because of how decorators works, Turbulette needs to import all resolvers it will find, that is, everything in the resolver package.

    Of course, you may have other packages holding your business logic, but it's strongly advised to not put them under the resolver package to not bloat imports at startup.

  • 📄 models.py

    Holds GINO models for this application. Turbulette won't look in other modules (unless they are imported in models), so you need all your models to be accessible here.


Last update: 2021-02-18