Skip to main content

JSON:API toolkit for Django Ninja

Project description

django-ninja-jsonapi

JSON:API toolkit for Django Ninja.

CI Package codecov PyPI Python Versions Django Versions PyPI Monthly Downloads Ruff ty uv

This project ports the core ideas of fastapi-jsonapi to a Django Ninja + Django ORM stack, following the JSON:API specification.

Full documentation is available at ignacemaes.com/django-ninja-jsonapi.

Status

  • Working baseline for resource registration and route generation (GET, GET LIST, POST, PATCH, DELETE).
  • Strict query parsing for JSON:API-style filter, sort, include, fields, and page parameters.
  • JSON:API exception payload handling.
  • Atomic operations endpoint wiring (/operations).
  • Django ORM data-layer baseline for CRUD + basic relationship handling.
  • Top-level/resource/relationship links in responses.
  • Django ORM include optimization (select_related/prefetch_related split) with optional include mapping overrides.
  • Logical filter groups (and/or/not) and cursor pagination (page[cursor]).
  • Content-type negotiation (415/406) per the JSON:API spec.
  • Attribute key inflection (dasherize or camelize).
  • Auto-generated relationship mutation routes (POST/PATCH/DELETE on to-many, PATCH on to-one).

Requirements

  • Python 3.10+
  • Django 4.2+
  • Django Ninja 1.0+

Install

uv add django-ninja-jsonapi

or

  • pip install django-ninja-jsonapi
  • poetry add django-ninja-jsonapi
  • pdm add django-ninja-jsonapi

Quick start

1) Define a Django model and a schema

from django.db import models
from pydantic import BaseModel


class Customer(models.Model):
    name = models.CharField(max_length=128)


class CustomerSchema(BaseModel):
    name: str

2) Create a JSON:API view class

from django_ninja_jsonapi import ViewBaseGeneric


class CustomerView(ViewBaseGeneric):
    pass

3) Register resources with ApplicationBuilder

from ninja import NinjaAPI

from django_ninja_jsonapi import ApplicationBuilder

api = NinjaAPI()
builder = ApplicationBuilder(api)

builder.add_resource(
    path="/customers",
    tags=["customers"],
    resource_type="customer",
    view=CustomerView,
    model=Customer,
    schema=CustomerSchema,
)

builder.initialize()

4) Mount API in Django URLs

from django.urls import path
from .api import api

urlpatterns = [
    path("api/", api.urls),
]

Example response

GET /api/customers/1/

{
  "data": {
    "type": "customer",
    "id": "1",
    "attributes": {
      "name": "Alice"
    },
    "links": {
      "self": "http://localhost:8000/api/customers/1/"
    }
  },
  "meta": {
    "count": 1
  }
}

GET /api/customers/

{
  "data": [
    {
      "type": "customer",
      "id": "1",
      "attributes": { "name": "Alice" },
      "links": { "self": "http://localhost:8000/api/customers/1/" }
    },
    {
      "type": "customer",
      "id": "2",
      "attributes": { "name": "Bob" },
      "links": { "self": "http://localhost:8000/api/customers/2/" }
    }
  ],
  "meta": {
    "count": 2
  }
}

Resources have a type and id at the top level while model fields are nested under attributes. Relationships, includes, sparse fieldsets, filtering, sorting and pagination all follow the JSON:API specification.

Architecture

The library provides two APIs. Both produce spec-compliant JSON:API responses through JSONAPIRenderer.

ApplicationBuilder — request flow

ApplicationBuilder auto-generates CRUD routes from a model + schema pair. Incoming requests flow through the full pipeline:

flowchart LR
    Client -->|HTTP request| NinjaAPI
    NinjaAPI --> ContentNegotiation
    ContentNegotiation --> ViewBase["ViewBase\n(generated endpoint)"]
    ViewBase --> QSM["QueryStringManager\n(parse filter / sort /\ninclude / fields / page)"]
    QSM --> DataLayer["DjangoORMDataLayer\n(apply filters, sorts,\nselect_related,\nprefetch_related)"]
    DataLayer --> DB[(Django ORM)]
    DB --> DataLayer
    DataLayer --> ViewBase
    ViewBase -->|"build response\n(relationships, links, meta)"| JSONAPIRenderer
    JSONAPIRenderer -->|"application/vnd.api+json"| Client

Standalone renderer — request flow

With setup_jsonapi(api) you write plain Django Ninja endpoints; the @jsonapi_resource decorator attaches config to the request and JSONAPIRenderer wraps the return value into a JSON:API document.

flowchart LR
    Client -->|HTTP request| NinjaAPI
    NinjaAPI --> Decorator["@jsonapi_resource\n(attach resource config\nto request)"]
    Decorator --> Endpoint["User endpoint\n(custom query logic)"]
    Endpoint -->|"dict / Pydantic / Model"| JSONAPIRenderer
    JSONAPIRenderer -->|"application/vnd.api+json"| Client

For full standalone usage (pagination, relationships, OpenAPI schemas, request body parsing, CRUD example), see the standalone renderer docs.

Configuration

Set JSON:API options in Django settings:

NINJA_JSONAPI = {
    "MAX_INCLUDE_DEPTH": 3,
    "MAX_PAGE_SIZE": 20,
    "ALLOW_DISABLE_PAGINATION": True,
    "INCLUDE_JSONAPI_OBJECT": False,
    "JSONAPI_VERSION": "1.0",
    "INFLECTION": "dasherize",  # or "camelize", or None (default)
}

Additional view/schema options:

  • django_filterset_class on a ViewBaseGeneric subclass to enable optional django-filter integration.
  • JSONAPIMeta.meta_fields (or Meta.meta_fields) on schema classes to expose selected fields in resource meta.

Exported public API

from django_ninja_jsonapi import (
    ApplicationBuilder,
    QueryStringManager,
    HTTPException,
    BadRequest,
    ViewBaseGeneric,
    JSONAPIRenderer,
    jsonapi_resource,
    jsonapi_include,
    jsonapi_meta,
    jsonapi_links,
)

Contributing

See CONTRIBUTING.md for setup, local checks, contribution workflow, and maintainer release notes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_ninja_jsonapi-0.7.0.tar.gz (58.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_ninja_jsonapi-0.7.0-py3-none-any.whl (82.8 kB view details)

Uploaded Python 3

File details

Details for the file django_ninja_jsonapi-0.7.0.tar.gz.

File metadata

  • Download URL: django_ninja_jsonapi-0.7.0.tar.gz
  • Upload date:
  • Size: 58.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_ninja_jsonapi-0.7.0.tar.gz
Algorithm Hash digest
SHA256 7f60893d54d333a00e4b11707f0799f1df7a3506c32e5a12224b62b6b18058d6
MD5 748971e4ef14062032396cc962f2a665
BLAKE2b-256 2784dbfa18f857b6f3a040fc28048b5c6ee82d2ff6272c1d02cdd4942841f591

See more details on using hashes here.

File details

Details for the file django_ninja_jsonapi-0.7.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_ninja_jsonapi-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6c3064ab88e32eee41eed49dfa2fcab8231a6d88a9ed02b543fab9981597bfa7
MD5 27f2959a71aac72b4175d194ce3be11a
BLAKE2b-256 e4b61416c023b6b7da3e60baad0e8500f2fa5b5ee75ab2df074d307f5984b948

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page