django-modern-rest

repository·master·Indexed 23 days ago

https://github.com/wemake-services/django-modern-rest

A modern REST framework for Django providing strict type safety, async support, and pluggable schema validation using Pydantic, msgspec, or attrs. It features high-performance JSON parsing, built-in OpenAPI schema generation, and compatibility with both WSGI and ASGI environments. The framework includes tools for migrating from Django REST Framework and Django Ninja, as well as a management command for exporting OpenAPI schemas.

Tokens
38.1K
Snippets
35
Records
261
Agent score
76%

What's inside django-modern-rest

  1. Overview of django-modern-rest

    master

    django-modern-rest is a modern REST framework for Django that provides strict type safety, schema validation, and support for both synchronous and asynchronous APIs. It is designed to be a high-performance alternative that integrates seamlessly with existing Django applications without reinventing core Django concepts.

    Key Features

    • Semantic REST APIs: 100% typed APIs with strict schema validation for both requests and responses.
    • High Performance: Optimized import times and single-pass validation. Supports msgspec for up to 15x faster performance compared to alternatives.
    • Sync and Async Support: Full support for both wsgi and asgi environments, allowing you to write APIs as sync or async.
    • First-class OpenAPI: Built-in OpenAPI schema generation, modification, and validation/testing tools (powered by schemathesis).
    • Django Compatibility: Works with existing Django packages and features; it simply adds fast JSON parsing and schema enforcement.
    • Extensibility: Every part of the framework is customizable and designed to be extended via a stable public API.
  2. What is migrated during a Django Ninja to DMR migration

    master

    The dmr-from-django-ninja skill focuses on migrating the transport layer while intentionally leaving business logic untouched.

    The following components are migrated:

    • Routing: Ninja root wiring and URL setup are converted to DMR router + Django URL includes.
    • Handlers: @api_controller and @http_* handlers are converted to dmr.controller.Controller.
    • Data Transfer Objects (DTOs): ninja.Schema models are converted to typed request and response DTOs.
    • Security/Traffic Control: Auth and throttling behavior are migrated using project-native integrations.

    Migration Reporting: The tool provides reports categorized by:

    • preserved behavior
    • approved drift
    • unresolved gaps
  3. What is streaming in django-modern-rest?

    master

    Streaming is used for single-directional event streams (e.g., LLM responses, logs, telemetry, live locations) instead of standard REST responses that return a complete data set at once.

    Streaming establishes a persistent connection and accepts headers with the content type application/jsonl (JSON Lines) or text/event-stream (Server-Sent Events), sending individual events one by one as they are produced.

    Requirement: All streaming modes require Django to be running in ASGI mode in production.

  4. Choose a throttling algorithm

    master

    Algorithms define how requests are counted.

    • SimpleRate (Default): Uses a fixed window. When the window expires, the count resets. This allows a 'boundary burst' where a client can send N requests at the end of one window and N at the start of the next, totaling 2N in a short interval. Best for general-purpose or admin endpoints.
    • LeakyBucket: Uses a continuous drain. Tokens leak at a steady rate, smoothing out traffic and preventing boundary bursts. Highly recommended for auth endpoints (login, OTP, password reset) and public APIs to prevent abuse.
    AlgorithmWindow TypeBoundary Burst RiskBest suited for
    SimpleRateFixedYesGeneral-purpose, internal, admin
    LeakyBucketContinuousNoAuth endpoints, public APIs
  5. Understand what is migrated during a DRF to DMR transition

    master

    The dmr-from-drf skill focuses on migrating the transport layer while intentionally leaving business logic untouched.

    The following components are migrated:

    • Routing: DRF router and URL setup are converted to DMR router and Django URL includes.
    • Handlers: APIView, GenericAPIView, and ViewSet handlers are converted to dmr.controller.Controller.
    • Data Transfer: DRF serializers are converted to typed request and response DTOs.
    • Behavior: Auth, permissions, throttling, pagination, and filtering behavior are migrated using project-native integrations.

    Migration Reporting: The tool provides reporting categorized by:

    • preserved behavior: Elements that match the original DRF implementation.
    • approved drift: Changes that are intentional and acceptable.
    • unresolved gaps: Areas where the migration could not be completed automatically.
  6. Understand Semantic Schema in django-modern-rest

    master

    A semantic schema in django-modern-rest is a comprehensive definition of an API's behavior. Unlike basic OpenAPI schemas, a semantic schema includes details such as:

    • All possible response schemas.
    • Content types.
    • Status codes.
    • Cookies and headers that can be set.

    This schema is used for two primary purposes: driving internal response validation and building the final OpenAPI specification. The framework enforces this schema strictly: if an endpoint attempts to return a status code, header, or cookie not defined in the schema, the request is rejected.

    When using features like authentication, the auth instance automatically injects its own schema requirements (e.g., adding 401 to the response list) into the endpoint's schema.

  7. Use Real Endpoints for granular response control

    master

    Real endpoints are used when you need full control over the response. Unlike raw endpoints, no response spec is generated by default for real endpoints; you must provide them manually using ResponseSpec.

    You can specify response specs using:

    1. The @validate decorator.
    2. The responses attribute on a Controller.
    3. The global responses setting in dmr.settings.Settings.

    At least one explicit response spec is required when using the @validate decorator.

  8. Choose a view implementation: Minimalistic vs. Detailed

    master

    When implementing views to convert models to schemas, you can choose between two primary approaches depending on your project's needs for speed versus correctness.

    Minimalistic Approach

    Uses built-in converters like UserSchema.model_validate(user_instance) (for Pydantic) or msgspec.convert (for msgspec).

    • Pros: Short, easy to write, low boilerplate.
    • Cons: Errors only appear at runtime (during tests). If you remove a field from a model that the schema still expects, type-checkers like Mypy will not warn you; the API will simply crash when executed.

    Detailed Approach

    Manually maps model attributes to the schema fields.

    • Pros: High correctness. If a model field is removed, your type-checker (e.g., Mypy) will immediately flag the error in your view code.
    • Cons: More verbose code.
  9. Compare JWT vs Opaque Tokens for authentication

    master

    When choosing a token-based authentication strategy, consider the trade-offs between statelessness and revocation capabilities.

    FeatureJWTOpaque Token
    StorageStateless, no database lookupRow in the database, looked up per request
    RevocationHard: valid until expiry, needs a blocklistEasy: revoked_at is set, token is dead instantly
    Token sizeLarger, carries claims in the payloadSmall, just a random string
    Per-request costSignature verification, no I/OOne DB read per request (plus optional write)
    Best fitHigh-throughput / distributed servicesAPIs needing instant logout, audit trails, or metadata
    • Use Opaque Tokens if you need instant revocation or per-token state (last used, scopes, device info).
    • Use JWT if you need to skip database lookups on every request and can tolerate tokens remaining valid until they expire.
  10. Understand the throttling execution lifecycle

    master

    Throttling occurs in two distinct stages to balance security and functionality:

    1. Before Auth: Protects the authentication process and content negotiation from brute-force and DoS attacks. This stage typically uses IP-based keys (RemoteAddr).
    2. After Auth: Allows throttling rules to be based on authenticated user information (e.g., UserPk).

    Warning: It is strongly recommended to have throttling (like IP-based checks) before authentication to protect against brute-force attacks. You can customize when keys execute, but avoid running auth-based throttling before the user is authenticated.