Introducción al uso de Django REST Framework

Índice

¿Por qué estudiar Django REST Framework (DRF)?

Instalación de Django REST Framework

Conceptos básicos de serialización

Serialización de datos en Python

Serialización de conjuntos de consultas en Django

¿Qué es una API que cumple con las especificaciones RESTful?

Protocolo, dominio y versiones

URI (Identificador Uniforme de Recursos)

Métodos HTTP

Filtrado

Códigos de estado

APIs con Hypermedia

¿Por qué aprender Django REST Framework (DRF)?

Django no fue diseñado específicamente para crear APIs web que sigan las normas REST, sin embargo, gracias a Django REST Framework (DRF) podemos desarrollar rápidamente APIs web robustas y estandarizadas. DRF proporciona un conjunto de herramientas poderosas y flexibles para cosntruir APIs web dentro del ecosistema de Django, incluyendo serializadores, autenticación, permisos, paginación, filtrado y control de tasa. Por esta razón, DRF amplía significativamente el potencial de Django, reduciendo así la posibilidad de que sea obsoleto.

Instalación de Django REST Framework

Django REST Framework (DRF) es un marco de trabajo RESTful basado en Django que facilita el desarrollo rápido de APIs con estilo RESTful. La documentación oficial se encuentra en:

DRF puede instalarse mediante pip, siempre que Django ya esté instalado previamente.

pip install djangorestframework


Si deseas una interfaz gráfica para interactuar con tus APIs, debes registrar rest_framework en la lista INSTALLED_APPS de tu proyecto, como se muestra a continuación:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'tu_app', # Tu aplicación personal
]


Ya tenemos instalado DRF, pero antes de comenzar a usarlo para desarrollar APIs, necesitamos comprender dos conceptos fundamentales: ¿qué es la serialización de datos y qué significa una API que cumple con las especificaciones RESTful? Estos conocimientos son esenciales para entender los serializadores y la estructura de URLs en DRF.

Conceptos básicos de serialización

Cada lenguaje de programación tiene sus propios tipos de datos. La serialización es el proceso de convertir objetos o estructuras de datos propias de un lenguaje en un formato que pueda ser transmitido por red o almacenado localmente (por ejemplo, JSON, XML o secuencias de bytes). El proceso inverso se denomina deserialización.

En el desarrollo de APIs, lo esencial es transformar los tipos de datos del backend en formatos universales y legibles, como JSON.

Serialización de datos en Python

Un ejemplo sencillo: el módulo json integrado en Python permite convertir estructuras comunes como listas o diccionarios en formato JSON usando el método dumps. Observa cómo los resultados están entre comillas simples, indicando que se ha convertido a una cadena JSON.

>>> import json
>>> json.dumps({"nombre":"Juan", "puntaje": 112})
'{"nombre": "Juan", "puntaje": 112}'


Serialización de conjuntos de consultas en Django

Dado que Django es un framework escrito en Python, los métodos de serialización mencionados anteriormente también son aplicables. Sin embargo, Django posee tipos de datos específicos como QuerySets y ValueQuerySets, además de clases de serialización incorporadas. Usendo django.core.serializers, puedes convertir fácilmente QuerySets en datos JSON.

# Convertir datos de QuerySet a JSON
from django.core import serializers
datos = serializers.serialize("json", SomeModel.objects.all())
datos1 = serializers.serialize("json", SomeModel.objects.all(), fields=('nombre','id'))
datos2 = serializers.serialize("json", SomeModel.objects.filter(campo = valor))


A veces solo necesitas ciertos campos de los resultados. Puedes usar .values('campo1', 'campo2') para obtener solo los datos requeridos, mejorando el rendimiento. Sin embargo, los resultados deben convertirse primero a una lista antes de serializarlos con json.dumps(). Ejemplo:

import json
from django.core.serializers.json import DjangoJSONEncoder

consulta = miModelo.objects.filter(foo_icontains=bar).values('f1', 'f2', 'f3')
datos4 = json.dumps(list(consulta), cls=DjangoJSONEncoder)


Aunque django.core.serializers puede serializar QuerySets en JSON, el verdadero poder radica en Django REST Framework. Los serializadores de DRF son más potentes, pueden generar automáticamente serializadores a partir de modelos y validan los datos entrantes desde el cliente.

¿Qué es una API que cumple con las especificaciones RESTful?

REST es un acrónimo de Representational State Transfer, introducido por Roy Fielding en su tesis de doctorado en 2000. En resumen, REST utiliza URIs para identificar recursos y métodos HTTP (GET, POST, PUT, DELETE) para operaciones CRUD sobre dichos recursos. Para que una API sea considerada RESTful, debe seguir estas restricciones. Existen muchas explicaciones detalladas sobre RESTful en línea, como los artículos de阮一峰 (Ruoyi Feng) o en Jianshu, pero aquí resumiremos los aspectos más importantes relevantes para nuestro uso.

Protocolo, dominio y versiones

Se recomienda usar HTTPS y asignar un dominio exclusivo para servicios API. Las versiones pueden incluirse en la URL o gestionarse mediante encabezados HTTP, por ejemplo:

https://api.ejemplo.com/v1
https://www.ejemplo.com/api/v1 


URI (Identificador Uniforme de Recursos)

En arquitecturas RESTful, cada URL representa un recurso. Esta dirección web se llama URI (Uniform Resource Identifier), también conocida como URL (Uniform Resource Locator). Dado que un URI representa un recurso, no debe contener verbos, solo sustantivos. Generalmente, los nombres de tablas en bases de datos representan colecciones, por lo tanto, los nombres de recursos en las APIs deben estar en plural.

https://api.ejemplo.com/v1/usuarios # Dirección de la colección de usuarios
https://api.ejemplo.com/v1/usuarios/{id} # Recurso específico del usuario con id=5. Nota: debería ser usuarios/5, no user/5
https://api.ejemplo.com/v1/usuarios/{id}/articulos # Artículos publicados por el usuario con id=5


Un desarrollador convencional podría diseñar URLs para edición o eliminación como:

https://api.ejemplo.com/v1/usuarios/{id}/editar/ # Editar usuario
https://api.ejemplo.com/v1/usuarios/{id}/eliminar/ # Eliminar usuario


Este diseño no cumple con las reglas RESTful. Un URI debe representar un recurso y no contener acciones. Los recursos deben permanecer fijos; las operaciones se realizan mediante diferentes métodos HTTP. Ejemplos típicos:

[POST]    https://api.ejemplo.com/v1/usuarios   // Crear nuevo usuario
[GET]     https://api.ejemplo.com/v1/usuarios/1 // Obtener información del usuario
[PATCH]   https://api.ejemplo.com/v1/usuarios/1 // Actualizar parcialmente
[PUT]     https://api.ejemplo.com/v1/usuarios/1 // Reemplazar completamente
[DELETE]  https://api.ejemplo.com/v1/usuarios/1 // Eliminar usuario


Cuando las URLs son largas, se recomienda usar guiones medios (-) en lugar de guiones bajos (_) y evitar terminar con barras (/).

https://api.ejemplo.com/v1/gestion-usuarios/usuarios/{id} # Correcto
https://api.ejemplo.com/v1/gestion_usuarios/usuarios/{id} # Incorrecto
https://api.ejemplo.com/v1/gestion-usuarios/usuarios/{id}/ # Incorrecto


Métodos HTTP

Los cinco métodos HTTP más utilizados son (con sus comandos SQL correspondientes):

GET (SELECT): Recuperar datos del servidor.
POST (CREATE): Crear un nuevo recurso en el servidor.
PUT (UPDATE): Actualizar un recurso completo en el servidor.
PATCH (UPDATE): Actualizar solo ciertas propiedades de un recurso.
DELETE (DELETE): Eliminar un recurso del servidor.


Otros métodos menos comunes son HEAD y OPTIONS. HEAD es similar a GET, pero no devuelve el cuerpo de la respuesta. OPTIONS se usa raramente y sirve para obtener los métodos soportados por una URL.

Nota del autor: A diferencia de Django tradicional, DRF soporta todos estos métodos HTTP.

Filtrado

Cuando hay muchos registros, no es viable devolverlos todos. Una API RESTful debe permitir filtros. Algunos ejemplos comunes de parámetros de filtrado:

?limite=10: Número máximo de registros a devolver.
?inicio=10: Posición inicial de los registros.
?pagina=2&por_pagina=100: Página actual y cantidad de elementos por página.
?ordenar_por=nombre&direccion=asc: Ordenar por nombre ascendente.
?tipo_usuario=1: Filtro por tipo de usuario.


Nota del autor: DRF puede combinarse fácilmente con django-filter para implementar filtros avanzados.

Códigos de estado

Tras procesar una solicitud, el servidor debe responder con un código de estado y mensaje. Algunos códigos comunes son:

200 OK - [GET]: Éxito en la obtención de datos, operación idempotente.
201 CREATED - [POST/PUT/PATCH]: Se creó o modificó un recurso exitosamente.
202 ACCEPTED - [*]: Solicitud recibida, procesamiento en segundo plano.
204 NO CONTENT - [DELETE]: Recurso eliminado correctamente.
400 BAD REQUEST - [POST/PUT/PATCH]: Error en la solicitud, no se realizó cambio.
401 UNAUTHORIZED - [*]: Falta de permiso (token, usuario o contraseña incorrectos).
403 FORBIDDEN - [*]: Permisos válidos pero acceso denegado.
404 NOT FOUND - [*]: El recurso solicitado no existe, operación idempotente.
406 NOT ACCEPTABLE - [GET]: Formato solicitado no disponible.
410 GONE - [GET]: El recurso fue eliminado permanentemente.
422 UNPROCESSABLE ENTITY - [POST/PUT/PATCH]: Error de validación al crear objeto.
500 INTERNAL SERVER ERROR - [*]: Error interno del servidor.


Nota del autor: DRF permite especificar fácilmente distintos códigos de estado en las respuestas.

APIs con Hypermedia

Una API RESTful idealmente debería incluir hiperenlaces a otras operaciones, permitiendo a los usuarios navegar sin necesidad de consultar documentación. Por ejemplo, al acceder a la raíz de api.ejemplo.com, se podría recibir:

{"enlaces": {
  "rel":   "colección https://www.ejemplo.com/zoológicos",
  "href":  "https://api.ejemplo.com/zoológicos",
  "título": "Lista de zoológicos",
  "tipo":  "application/vnd.formato-tuyo+json"
}}


Nota adicional: DRF ofrece soporte nativo para HyperLinkedModel, facilitando este tipo de implementación.

Etiquetas: Django REST API Serialización DRF

Publicado el 8-15 04:23