Skip to main content

JSON:API toolkit for Django Ninja

Project description

django-ninja-jsonapi

JSON:API toolkit for Django Ninja.

CI Package PyPI Ruff ty

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.4.0.tar.gz (50.3 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.4.0-py3-none-any.whl (72.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for django_ninja_jsonapi-0.4.0.tar.gz
Algorithm Hash digest
SHA256 262d456a014c0142b8adf6f79b86c5cbff5ed8012730e45c6ee47266247ecfb1
MD5 63920740235574d3578d1cefb9e7385c
BLAKE2b-256 a82b873332f8a1d9c6aecd66d699c179e289b507a4ea33e10ebbc99c2a3f2287

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_ninja_jsonapi-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b21f0da9d88892b7d0a92b08f97b2e63e6f4ca52d72aa8bde0809985152d3086
MD5 1e454c144767bd4e5238bc7c2883ce01
BLAKE2b-256 3c086dbc6379b008468291dcfe37a0d1d0f499bd953102bee9548d7e1c695046

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