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.5.0.tar.gz (51.6 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.5.0-py3-none-any.whl (74.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_ninja_jsonapi-0.5.0.tar.gz
  • Upload date:
  • Size: 51.6 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.5.0.tar.gz
Algorithm Hash digest
SHA256 b03f08a997ab195d2e0400831bf664ee5128e7c235af228cbfcf9165251ed52e
MD5 473d91a7da2e27d91fc586c71b5e3ab7
BLAKE2b-256 95e64682fa01e6488fd54720cc442c7dd1290a04a9e0fd14c7e6692b3c83d8b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_ninja_jsonapi-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 767208c6fa56dce73f21ec91b45e98df118a40cbd2877c777f93d8b846353cc1
MD5 a009ec74e075cd57c35ed72603c6fea3
BLAKE2b-256 42acc4f21011f71dea54b8a1d091d4a5086224501f7f6adf66c48dc9424ac1f0

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