paint-brush
Esquema de OpenAPI 3.0 con Swagger UI para la aplicación Django RESTfulpor@spyker77
19,863 lecturas
19,863 lecturas

Esquema de OpenAPI 3.0 con Swagger UI para la aplicación Django RESTful

por Evgeni Sautin8m2020/12/04
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Usemos drf-spectacular para simplificar la creación de hermosos documentos para su aplicación Django de acuerdo con la especificación OpenAPI versión 3. ¿Suena fácil? no era para mi...

Company Mentioned

Mention Thumbnail
featured image - Esquema de OpenAPI 3.0 con Swagger UI para la aplicación Django RESTful
Evgeni Sautin HackerNoon profile picture

Usemos drf-spectacular para simplificar la creación de hermosos documentos para su aplicación Django de acuerdo con la especificación OpenAPI versión 3. ¿Suena fácil? no era para mi...

Dado que todavía soy un programador relativamente novato, lucho constantemente con diferentes temas y casi siempre buscar ayuda en Google. Pero no en este caso. Decidí agregar el marco Django REST a mi cadena de herramientas y combinarlo con tecnologías como OAS 3.0. Vi lo genial que se vería la documentación de la API cuando descubrí FastAPI por primera vez y quise implementar la interfaz de usuario de Swagger en mi propia aplicación.

La opción más popular, en mi opinión, fue drf-yasg, pero dice explícitamente que "es poco probable que drf-yasg obtenga soporte para OpenAPI 3.0 pronto, o nunca". Bueno, la segunda mejor opción en esta dirección es drf-espectacular, pero no pude averiguar cómo documentar mi API simplemente siguiendo los ejemplos proporcionados (por cierto, lo hice por primera vez).

La solución que se me ocurrió es crear documentación con herramientas DRF estándar (la forma más fácil), luego generar esquemas OpenAPI 2 con drf-yasg (ya que tiene una descripción más completa del proceso) y finalmente ajustar la configuración para usar drf-espectacular .

Aquí voy a acortar esta ruta para usted usando el ejemplo de inicio rápido de la documentación de DRF y agregando algo de personalización para implementar la interfaz de usuario de Swagger con la versión 3 de la especificación. Así que, sin más preámbulos, ¡sé valiente y sígueme!

Marco REST de Django

Comenzamos con un par de pasos que son ligeramente diferentes de la documentación oficial de DRF. Omitiré algunos detalles específicos del marco en sí y si siente que le falta información para su propia implementación, simplemente explore el sitio oficial o haga una pregunta en la sección de comentarios a continuación.

1. Configuración del proyecto

Lo primero es lo primero, cree el directorio del proyecto e ingréselo.

 mkdir tutorial cd tutorial

Luego verifique si pipenv está instalado para crear un entorno virtual y aislar las dependencias de su paquete.

 pip3 install pipenv

Instale Django y Django REST framework en el entorno virtual.

 pipenv install django pipenv install djangorestframework

Activar entorno virtual.

 pipenv shell

Ahora, después de un poco de preparación, es hora de configurar un nuevo proyecto con una sola aplicación. Tenga en cuenta el final "." carácter - no es un error tipográfico.

 django-admin startproject config . django-admin startapp quickstart

Como verificación intermedia, comparemos el diseño de nuestro proyecto, que en este punto debería verse así.

Ahora sincronice la base de datos por primera vez, lo que agregará un nuevo archivo SQLite al diseño mencionado anteriormente.

 python manage.py migrate

Después de una migración exitosa, cree un administrador de usuario inicial con contraseña password123 . Se le pedirá que ingrese la contraseña a ciegas.

 python manage.py createsuperuser --email [email protected] --username admin

2. Serializadores

¡Arremangarse porque estamos empezando a codificar más!

Dentro de su directorio de tutoriales, ejecute el siguiente comando para crear un nuevo

 serializers.py
expediente.

 touch quickstart/serializers.py

Abra este archivo recién creado con su IDE favorito y llénelo con el siguiente contenido.

 from django.contrib.auth.models import User, Group from rest_framework import serializers class UserSerializer (serializers.HyperlinkedModelSerializer) : class Meta : model = User fields = [ 'url' , 'username' , 'email' , 'groups' ] class GroupSerializer (serializers.HyperlinkedModelSerializer) : class Meta : model = Group fields = [ 'url' , 'name' ]

3. Vistas

Después de eso, abre

 quickstart/views.py
y comience a escribir o simplemente copie y pegue, como desee, sin juzgar 😉

 from django.contrib.auth.models import User, Group from rest_framework import viewsets from rest_framework import permissions from .serializers import UserSerializer, GroupSerializer class UserViewSet (viewsets.ModelViewSet) : """ API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all().order_by( "-date_joined" ) serializer_class = UserSerializer permission_classes = [permissions.IsAuthenticated] class GroupViewSet (viewsets.ModelViewSet) : """ API endpoint that allows groups to be viewed or edited. """ queryset = Group.objects.all() serializer_class = GroupSerializer permission_classes = [permissions.IsAuthenticated]

En lugar de escribir varias vistas, todo el comportamiento común se agrupa en clases denominadas ViewSets. Para fines futuros, puede dividirlos fácilmente en vistas individuales si es necesario, pero el uso de conjuntos de vistas mantiene la lógica de vista bien organizada y muy concisa.

4. URL

Es hora de que las URL de la API estén disponibles. Navegue a la carpeta de configuración y cambie

 urls.py
contenido a lo siguiente.

 from django.urls import include, path from rest_framework import routers from quickstart import views router = routers.DefaultRouter() router.register( r"users" , views.UserViewSet) router.register( r"groups" , views.GroupViewSet) # Wire up our API using automatic URL routing. # Additionally, login URLs included for the browsable API. urlpatterns = [ path( "" , include(router.urls)), path( "api-auth/" , include( "rest_framework.urls" , namespace= "rest_framework" )), ]

5. Paginación

La paginación le permite controlar cuántos objetos por página se devuelven. Para habilitarlo, agregue las siguientes líneas en la parte inferior de

 config/settings.py

 REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS" : "rest_framework.pagination.PageNumberPagination" , "PAGE_SIZE" : 10 , }

En realidad, no necesitamos esta configuración a menos que decidas llenar la base de datos con muchos datos más adelante.

6. Configuración

dentro del mismo

 settings.py
archivo, para fines de prueba, habilite todos los hosts agregando "*" a ALLOWED_HOSTS.

 ALLOWED_HOSTS = [ "*" ]

También agregue "rest_framework" a INSTALLED_APPS.

 INSTALLED_APPS = [ ... "rest_framework" , ]

7. Prueba de la API

Es hora de probar lo que hemos logrado hasta ahora. Iniciemos el servidor.

 python manage.py runserver

Ahora en su navegador abra la URL http://127.0.0.1:8000/users/ . Probablemente esté viendo la página como esta, lo que significa que debe iniciar sesión (esquina superior derecha) con las credenciales de superusuario que creó al final del paso 1.

Después de un inicio de sesión exitoso, la página debería verse así. Si es así, ¡buen trabajo!

Hasta aquí todo bien y pasemos al siguiente paso: ¡cambiar esta interfaz de usuario bastante elegante a la increíble Swagger!

drf-espectacular

Primero, detenga el servidor presionando CONTROL-C. Después de esto, debe instalar drf-spectacular en su entorno virtual.

 pipenv install drf-spectacular

Entonces, en

 settings.py
agregue drf-espectacular a las aplicaciones instaladas. A estas alturas, el resultado debería ser así.

 INSTALLED_APPS = [ "django.contrib.admin" , "django.contrib.auth" , "django.contrib.contenttypes" , "django.contrib.sessions" , "django.contrib.messages" , "django.contrib.staticfiles" , "rest_framework" , "drf_spectacular" , ]

Finalmente, registre AutoSchema con DRF agregando una línea adicional a la configuración REST_FRAMEWORK también dentro

 settings.py
archivo para que el resultado se vea así.

 REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS" : "rest_framework.pagination.PageNumberPagination" , "PAGE_SIZE" : 10 , "DEFAULT_SCHEMA_CLASS" : "drf_spectacular.openapi.AutoSchema" , }

Al momento de escribir este texto, la versión más reciente de drf-spectacular es la 0.11.1. Por lo tanto, tenga en cuenta que puede haber algunos cambios importantes en el código, ya que todavía está por debajo de 1.xx y en desarrollo activo.

OpenAPI 3.0 con interfaz de usuario de Swagger

Y ahora la parte más complicada, que fue especialmente difícil para mí. Con suerte, evitarás la miseria por la que pasé y saltarás directamente a la parte feliz 🎊

1. URL

Cambiar a la

 urls.py
dentro de la carpeta de configuración y modifique el contenido de la siguiente manera.

 from django.urls import include, path from rest_framework import routers from quickstart import views from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView router = routers.DefaultRouter() router.register( r"users" , views.UserViewSet) router.register( r"groups" , views.GroupViewSet) # Wire up our API using automatic URL routing. # Additionally, login URLs included for the browsable API. urlpatterns = [ path( "" , include(router.urls)), path( "api-auth/" , include( "rest_framework.urls" , namespace= "rest_framework" )), # OpenAPI 3 documentation with Swagger UI path( "schema/" , SpectacularAPIView.as_view(), name= "schema" ), path( "docs/" , SpectacularSwaggerView.as_view( template_name= "swagger-ui.html" , url_name= "schema" ), name= "swagger-ui" , ), ]

Básicamente, acaba de agregar una nueva importación y se requieren dos rutas para la interfaz de usuario de Swagger.

2. Plantilla

Ahora vamos a crear una carpeta para una plantilla de documentación API personalizada con un nuevo archivo dentro. Supongo que su terminal permanece en el mismo directorio raíz todo este tiempo: tutorial.

 mkdir templates touch templates/swagger-ui.html

Entonces abre

 swagger-ui.html
y pega el siguiente código. Solo una nota rápida: tuve dificultades incluso con este fragmento de código tomado de la documentación de DRF , por lo que ha cambiado un poco, aunque puede parecer familiar.

 <!DOCTYPE html> < html > < head > < title > Swagger </ title > < meta charset = "utf-8" > < meta name = "viewport" content = "width=device-width, initial-scale=1" > < link rel = "stylesheet" type = "text/css" href = "https://unpkg.com/swagger-ui-dist@3/swagger-ui.css" > </ head > < body > < div id = "swagger-ui" > </ div > < script src = "https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js" > </ script > < script > const ui = SwaggerUIBundle({ url : "{% url 'schema' %}" , dom_id : '#swagger-ui' , presets : [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ], layout : "BaseLayout" , requestInterceptor : ( request ) => { request.headers[ 'X-CSRFToken' ] = "{{ csrf_token }}" return request; } }) </ script > </ body > </ html >

3. Configuración

Y de nuevo volver a

 settings.py
dentro de la carpeta de configuración. Busque TEMPLATES y cambie la línea "DIRS" para que todo el bloque sea el siguiente para decirle a Django dónde buscar nuestra plantilla personalizada.

 TEMPLATES = [ { "BACKEND" : "django.template.backends.django.DjangoTemplates" , "DIRS" : [BASE_DIR / "templates" ], "APP_DIRS" : True , "OPTIONS" : { "context_processors" : [ "django.template.context_processors.debug" , "django.template.context_processors.request" , "django.contrib.auth.context_processors.auth" , "django.contrib.messages.context_processors.messages" , ], }, }, ]

Verificación final del diseño del proyecto solo para asegurarnos de que estamos en la misma página.

Después de todas esas configuraciones, activemos el servidor y abramos la URL http://127.0.0.1:8000/docs/

¡He aquí! La documentación de la interfaz de usuario de Swagger implementada en el estándar OpenAPI 3.0 🎉

Las mejoras adicionales solo dependen de usted, pero hay un par de ideas:

  • ampliar la gama de formatos de datos disponibles, por ejemplo, con djangorestframework-xml o djangorestframework-yaml ;
  • use el decorador @extend_schema para agregar información adicional a sus vistas;
  • anule la configuración predeterminada especificando SPECTACULAR_SETTINGS en settings.py;
  • cree una página de marca aplicando su propio CSS a la plantilla de documentos;