Skip to content

slowfound/django-next-e2e-type-safety

Repository files navigation

Django + Next.js End-to-End Type-Safe API Setup

Table of Contents


Overview

This project provides a full-stack, type-safe web application combining Django REST Framework (DRF) and Next.js. It uses drf-spectacular to automatically generate an OpenAPI schema from Django serializers, and @hey-api/openapi-ts on the Next.js side to generate a fully typed TypeScript client.

With this setup:

  • The backend defines the API schema via Django serializers and views.
  • The frontend consumes it safely with auto-generated TypeScript clients.
  • Traefik handles HTTPS routing and certificate management.
  • Docker Compose orchestrates everything: Django, Next.js, PostgreSQL, Redis, and Traefik.

Features

  • End-to-End Type Safety: Django serializers → OpenAPI → TypeScript client.
  • Auto-Generated API Client: Managed via @hey-api/openapi-ts.
  • Cookie-Based Auth: Secure login and refresh tokens stored as HTTP-only cookies.
  • Full Docker Support: Run Django, Next.js, Postgres, and Redis with a single command.
  • Traefik Reverse Proxy: Automatic HTTPS and routing with Let's Encrypt.
  • Live OpenAPI Docs: Auto-generated /api/schema/swagger-ui/ endpoint.
  • Developer-Friendly Scripts: Simplified commands for schema generation and client updates.

Architecture

                   ┌───────────────────────────┐
                   │         Traefik           │
                   │  HTTPS + Reverse Proxy    │
                   └──────────┬────────────────┘
                              │
      ┌───────────────────────┼───────────────────────┐
      │                       │                       │
┌───────────────┐     ┌────────────────┐      ┌──────────────────┐
│   Next.js     │     │    Django DRF  │      │   PostgreSQL     │
│ (Frontend)    │     │ (Backend API)  │      │ (Data Storage)   │
│ @hey-api      │<--->│ drf-spectacular│      │                  │
└───────────────┘     └────────────────┘      └──────────────────┘
                              │
                       ┌──────────────┐
                       │    Redis     │
                       │ (Cache/Celery│
                       │   Backend)   │
                       └──────────────┘

Prerequisites

  • Docker: Install Docker
  • Docker Compose: Install Docker Compose
  • Domain Name: For serving HTTPS via Traefik.
  • Node.js + pnpm: (only required for local development on the Next.js app)

Installation

  1. Clone the Repository

    git clone https://github.com/yourusername/django-next-type-safe-api.git
    cd django-next-type-safe-api
  2. Create Environment File

    cp .env.example .env

    Edit .env with your configuration values (see Environment Variables).

  3. Create Traefik Network

    docker network create traefik-public
  4. Build and Start the Stack

    docker compose -f docker-compose.yml -f docker-compose-traefik.yml up --build

    This builds all containers and starts the stack in the background.


Configuration

Environment Variables

Variable Description Example
ROOT_DOMAIN Base domain used for backend and frontend example.com
NEXT_DOMAIN Domain for the Next.js app app.example.com
DJANGO_SECRET_KEY Django secret key supersecretkey
POSTGRES_DB Database name app_db
POSTGRES_USER Database username app_user
POSTGRES_PASSWORD Database password securepassword
CORS_ALLOWED_ORIGINS Allowed origins for frontend requests https://app.example.com
ACME_EMAIL Email for Let's Encrypt certificate notifications admin@example.com

Docker Compose Services

Service Description
traefik Reverse proxy, SSL termination, auto certificates
django Django REST API backend
next Next.js frontend (SSR with API client)
postgres PostgreSQL database
redis Cache and Celery message broker

Volumes

Volume Purpose
./django:/app Django source code
./next:/app Next.js source code
./postgres_data PostgreSQL persistent data
traefik-public-certificates Let's Encrypt certificates

Usage

1. Access the Application

  • Frontend: https://app.example.com
  • Backend API Root: https://example.com/api/
  • Swagger UI: https://example.com/api/schema/swagger-ui/

2. Manage Services

# Start
docker compose up -d

# Stop
docker compose down

# Logs
docker compose logs -f

3. Create a Superuser

docker compose exec django python manage.py createsuperuser

OpenAPI Client Generation

The Next.js app uses the OpenAPI JSON generated by Django to build a fully typed TypeScript API client.

  1. Generate Schema (from Django)

    docker compose exec django python manage.py spectacular --file schema.yaml

    This outputs the latest OpenAPI schema from your Django app.

  2. Generate TypeScript Client

    Inside the Next.js directory:

    cd next
    pnpm openapi

    This runs two scripts:

    • pnpm openapi:download → downloads the latest OpenAPI JSON from Django.
    • pnpm openapi:generate → uses @hey-api/openapi-ts to build the typed client.
  3. Use the Client in Next.js

    import { apiTodosList, apiTodosCreate } from '@/client'
    
    const todos = await apiTodosList()
    const newTodo = await apiTodosCreate({ body: { title: 'Hello world' } })

Logging

Each service logs to standard output and can be viewed with Docker:

docker compose logs -f django
docker compose logs -f next

Backend: Django logging configuration in settings.py (JSON format optional). Frontend: Next.js logs in container output. Traefik: Access and error logs persisted for HTTPS routing diagnostics.


Troubleshooting

Issue Possible Cause Fix
Traefik not accessible Port 80/443 blocked Ensure ports 80 and 443 are open
Frontend cannot fetch API CORS or cookie config Check CORS_ALLOWED_ORIGINS and credentials settings
Schema not generating Missing drf-spectacular Run pip install drf-spectacular and restart
OpenAPI client outdated Backend schema changed Run pnpm openapi in next/ directory
Django migrations fail Postgres not ready Re-run docker compose up -d after DB starts

Contributing

Contributions are welcome! To add new features or fix bugs:

git checkout -b feature/your-feature
git commit -m "Add your feature"
git push origin feature/your-feature

Then open a Pull Request with a clear description.

About

Example project with Django and Next.js + End-to-End type-safety achieved through OpenAPI Specification

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors