Skip to main content

Django app that provides a hybrid router for Django Rest Framework

Project description

djangorestframework-hybridrouter

A router for ViewSets and APIViews, with a better browsable API and support for nested routers!

Inspired by this topic.

Overview

The HybridRouter class is an extension of Django REST Framework's DefaultRouter that allows you to register both ViewSets and APIViews. It provides more flexibility in managing your URL routes, offers a better browsable API experience, and supports nested routers.

Features

  • Register both ViewSets and APIViews using a unified interface.
  • Simplified URL patterns for better readability.
  • Automatic creation of intermediate API views for grouped endpoints (configurable).
  • Support for nested routers.
  • Automatic conflict resolution for basenames.

Installation

pip install djangorestframework-hybridrouter

Usage

Here’s an example of how to use the HybridRouter:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from django.urls import path, include
from hybridrouter import HybridRouter


class ServerConfigViewSet(ViewSet):
    def list(self, request):
        return Response({'a': 'b'})

class ServerConfigView(APIView):
    def get(self, request):
        return Response({'config': 'server'})

class ClientModsView(APIView):
    def get(self, request):
        return Response({'mods': 'client'})

class ServerModsView(APIView):
    def get(self, request):
        return Response({'mods': 'server'})

router = HybridRouter()
router.include_intermediate_views = True  # Enable intermediate API views

# Register APIViews
router.register('server-config', ServerConfigView, basename='server-config')
router.register('mods/client', ClientModsView, basename='mods-client')
router.register('mods/server', ServerModsView, basename='mods-server')

# Register a ViewSet
router.register('coucou', ServerConfigViewSet, basename='coucou')

# Register more APIViews under 'coucou' prefix
router.register('coucou/client', ClientModsView, basename='coucou-client')
router.register('coucou/server', ServerModsView, basename='coucou-server')

urlpatterns = [
    path('', include(router.urls)),
]

This configuration will generate URLs for both APIViews and ViewSets, and include intermediate API views for grouped endpoints.

Documentation

HybridRouter

  • register(prefix, view, basename=None)

    Registers an APIView or ViewSet with the specified prefix.

    • prefix: URL prefix for the view or viewset.
    • view: The APIView or ViewSet class.
    • basename: The base name for the view or viewset (optional). If not provided, it will be automatically generated.
  • register_nested_router(prefix, router)

    Registers a nested router under a specific prefix.

    • prefix: URL prefix under which the nested router will be registered.
    • router: The DRF router instance to be nested.

Attributes

  • include_intermediate_views (default True)

    Controls whether intermediate API views are automatically created for grouped endpoints. When set to True, the router will generate intermediate views that provide a browsable API listing of all endpoints under a common prefix.

Notes

  • Automatic Basename Conflict Resolution

    The HybridRouter automatically handles conflict resolution for basenames. If you register multiple views or viewsets with the same basename, it will assign unique basenames and log a warning.

  • Trailing Slash

    The HybridRouter uses a configurable trailing_slash attribute, defaulting to "/?" to match DRF’s SimpleRouter behavior.

Advanced Features

Custom Intermediary API Views

The HybridRouter can automatically create custom intermediary API views for grouped endpoints. This feature improves the organization of your API and provides a cleaner browsable interface.

Example:

router = HybridRouter()
router.include_intermediate_views = True  # Enable intermediate API views

router.register('server-config', ServerConfigView, basename='server-config')
router.register('server-config/map', ServerConfigView, basename='server-config')
router.register('server-config/health', ServerConfigView, basename='server-config')
router.register('mods/client', ClientModsView, basename='mods-client')
router.register('mods/server', ServerModsView, basename='mods-server')

With include_intermediate_views set to True, the router will create intermediate views at the mods/ prefix, providing a browsable API that lists both client and server endpoints under mods/. Also note that here for server-config/ endpoints an intermediate view will not be created because it's already registered.

Nested Routers

You can register nested routers under a specific prefix using register_nested_router. This allows you to include routers from other apps or create a complex URL structure.

Example:

from rest_framework.routers import DefaultRouter

nested_router = DefaultRouter()
nested_router.register('items', ItemViewSet, basename='item')

router = HybridRouter()
router.register_nested_router('nested/', nested_router)

urlpatterns = [
    path('', include(router.urls)),
]

In this example, all routes from nested_router will be available under the nested/ prefix.

Experimental Features

The automatic creation of intermediary API views is a feature that improves the browsable API experience. This feature is still in development and may not work as expected in all cases. Please report any issues or suggestions.

router = HybridRouter(enable_intermediate_apiviews=False)

router.register('server-config', ServerConfigView, name='server-config')
router.register('mods/client', ClientModsView, name='mods-client')
router.register('mods/server', ServerModsView, name='mods-server')
router.register('coucou/client', ClientModsView, name='coucou-client')
router.register('coucou/server', ServerModsView, name='coucou-server')
router.register('coucou', ServerConfigViewSet, basename='coucou')

With this configuration of the router with enable_intermediate_apiviewsset to False, the intermediary API views will not be created. So the browsable API will look like on a DefaultRouter :

image

But if you set enable_intermediate_apiviews to True, the intermediary API views will be created and the browsable API will look like this:

router = HybridRouter(enable_intermediate_apiviews=True)

image image

This improves the readability and the logic of the browsable API and provides a better user experience.

And as you can see that will not interfere with other already existing views. Here, the ServerConfigViewSet is still accessible through the coucou endpoint and as not been overridden by an intermediary API view.

Testing

The package includes comprehensive tests to ensure reliability. Here are some highlights:

  • Registering Views and ViewSets Tests registering both APIViews and ViewSets, ensuring that URLs are correctly generated and accessible.

  • Intermediate Views Tests the creation of intermediate views when include_intermediate_views is enabled or disabled.

  • Nested Routers Tests registering nested routers and ensuring that their routes are correctly included under the specified prefix.

  • Basename Conflict Resolution Tests automatic conflict resolution when multiple views or viewsets are registered with the same basename.

Notes

  • Compatibility

    The HybridRouter is designed to work seamlessly with Django REST Framework and is compatible with existing DRF features like schema generation.

  • Spectacular Support

    Will be added in the future. After some manual test, it seems that the spectacular package is compatible with the HybridRouter. But that may need some more testing.

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

djangorestframework_hybridrouter-1.0.2.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

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

File details

Details for the file djangorestframework_hybridrouter-1.0.2.tar.gz.

File metadata

File hashes

Hashes for djangorestframework_hybridrouter-1.0.2.tar.gz
Algorithm Hash digest
SHA256 de8ac5791daa1edbefe6d62f1d30535dd7764a7ceb5e13ef100349b167e09805
MD5 479dfb6f91b9ebb6b3a0c26362031841
BLAKE2b-256 2f5e955f7ee262adfc3f047ab4730c51074ed7ea30fc53fbf2f74b1abcb9d809

See more details on using hashes here.

File details

Details for the file djangorestframework_hybridrouter-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for djangorestframework_hybridrouter-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 90eff07858ea2dd4158862da15968b8a33d8f3cd471a267b2e31a0162e3d9405
MD5 dbacb1913d09afd6ba8015d9dbb659b7
BLAKE2b-256 8da98bd2730dc097d7e641f1a88616f1253ff238fe3fc5861ec1c08c968f0cfa

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