instalar - django-rest-framework: api versioning
django rest framework with django 2 (2)
Una forma de hacerlo es tener el control de versiones especificado como parte del tipo de medio.
Esto es lo que GitHub hace actualmente por su API .
También puede incluir parámetros de tipo de medios en sus encabezados de aceptación, por ejemplo, Accept: application/json; version=beta
Accept: application/json; version=beta
, que coincidirá con éxito contra JSONRenderer
. A continuación, puede codificar su vista para que se comporte de manera diferente según el tipo de medio aceptado, consulte here .
Hay muchos patrones diferentes para versionar en API, y no diría que todavía existe un gran consenso sobre el enfoque correcto, pero esa sería una posibilidad razonable.
Actualización de enero de 2015 : Mejor soporte de versiones será entrante en la versión 3.1.0. Ver [esta solicitud de extracción]
Actualización de marzo de 2015 : los documentos para la versión API están ahora disponibles .
( https://github.com/tomchristie/django-rest-framework/pull/2285 ) para más detalles.
así que buscar en Google parece que el consenso general es que incrustar números de versión en REST URI es una mala práctica y una mala idea.
incluso en SO hay defensores fuertes que apoyan esto.
Por ejemplo, ¿ Mejores prácticas para el control de versiones API?
Mi pregunta es acerca de cómo lograr la solución propuesta de usar la negociación aceptar encabezado / contenido en django-rest-framework para lograr esto.
Parece que la negociación de contenido en el marco,
http://django-rest-framework.org/api-guide/content-negotiation/ ya está configurado para devolver automáticamente los valores previstos en función de los tipos MIME aceptados. Si empiezo a usar el encabezado Aceptar para los tipos personalizados, perderé este beneficio del marco.
¿Hay una mejor manera de lograr esto en el marco?
ACTUALIZAR:
versionar ahora está soportado correctamente.
Hay algunas respuestas de su enlace:
Nos pareció práctico y útil poner la versión en la URL. Hace que sea fácil decir lo que estás usando de un vistazo. Hacemos alias / foo a / foo / (últimas versiones) para facilitar el uso, URL más cortas / más limpias, etc., como lo sugiere la respuesta aceptada. Mantener la compatibilidad hacia atrás para siempre suele ser prohibitivo y / o muy difícil. Preferimos dar aviso anticipado de desaprobación, redirecciones como las sugeridas aquí, documentos y otros mecanismos.
Así que tomamos este enfoque, además de permitirles a los clientes especificar la versión en el encabezado de la solicitud (versión X), así es como lo hicimos:
Estructura al costado de la aplicación API:
.
├── __init__.py
├── middlewares.py
├── urls.py
├── v1
│ ├── __init__.py
│ ├── account
│ │ ├── __init__.py
│ │ ├── serializers.py
│ │ └── views.py
│ └── urls.py
└── v2
├── __init__.py
├── account
│ ├── __init__.py
│ ├── serializers.py
│ └── views.py
└── urls.py
proyecto urls.py:
url(r''^api/'', include(''project.api.urls'', namespace=''api'')),
api app level urls.py:
from django.conf.urls import *
urlpatterns = patterns('''',
url(r'''', include(''project.api.v2.urls'', namespace=''default'')),
url(r''^v1/'', include(''project.api.v1.urls'', namespace=''v1'')),
)
nivel de versión urls.py
from django.conf.urls import *
from .account import views as account_views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(''account'', account_views.AccountView)
router.register(''myaccount'', account_views.MyAccountView)
urlpatterns = router.urls
crear un middleware para cambiar al código correcto cambiando el path_info, tenga en cuenta que hay una advertencia de que el espacio de nombres (''api'') definido en las URL del nivel del proyecto no es flexible y debe conocerse en el middleware:
from django.core.urlresolvers import resolve
from django.core.urlresolvers import reverse
class VersionSwitch(object):
def process_request(self, request):
r = resolve(request.path_info)
version = request.META.get(''HTTP_X_VERSION'', False)
if r.namespace.startswith(''api:'') and version:
old_version = r.namespace.split('':'')[-1]
request.path_info = reverse(''{}:{}''.format(r.namespace.replace(old_version, version), r.url_name), args=r.args, kwargs=r.kwargs)
URL de ejemplo:
curl -H "X-Version: v1" http://your.domain:8000/api/myaccount/