Serializer: o que é e como funciona no Django Rest Framework
Introdução
O desenvolvimento de APIs é uma parte fundamental na construção de sistemas modernos, pois ela permite a comunicação eficiente e flexível entre diferentes partes de uma aplicação ou sistemas distintos. E, no contexto do desenvolvimento em Django, o Django Rest Framework (DRF) apresenta ferramentas para a criação de APIs robustas.
Entretanto, nesse processo, precisamos destacar um componente essencial: os serializers do DRF, que atuam na manipulação e transmissão de dados. Mas afinal, o que é um serializer e como ele funciona no desenvolvimento de APIs utilizando o Django Rest Framework?
Vamos descobrir tudo isso ao longo desta leitura!
O que é um serializer?
Um serializer (em português, serializador) é um componente de software que converte dados complexos, como objetos ou estruturas de dados, em algum formato que pode ser facilmente transmitido ou armazenado e, posteriormente, reconstruído. Esse processo de conversão é conhecido como serialização.
Ao realizar a conversão de um objeto ou conjunto de dados, você o transforma em uma representação linear ou em um formato específico, como JSON, XML, YAML ou outros formatos binários. Essa representação serializada pode ser transmitida pela rede, gravada em um arquivo ou armazenada em um banco de dados.
Serializadores também fazem o processo oposto, chamado de desserialização, que reconstrói a estrutura original dos dados a partir da representação serializada. Isso permite que os dados sejam transmitidos, armazenados ou compartilhados entre diferentes sistemas de maneira eficiente.
Como funciona o serializer no DRF?
Assim como o Django utiliza o ORM (Object-Relational Mapping) para simplificar a interação com classes de modelos e facilitar a comunicação eficiente com o banco de dados, o Django REST Framework emprega uma abordagem semelhante ao criar serializers com classes em Python otimizando a manipulação de dados em APIs.
Podemos conferir um esquema de como acontece esse processo:
Como podemos notar, a interação dos tipos de dados se dá com o model interagindo com o banco de dados por meio do ORM, na qual executa as operações de consulta, atualização, criação ou exclusão de dados no banco de dados.
Os dados retornados do banco, nesse processo, são querysets ou instâncias da classe criada no Model, que podemos definir como uma representação da consulta ao banco de dados no Django em formato de objetos complexos.
Esses dados são enviados para os serializadores, que são classes que especificam como converter objetos complexos, em formatos de dados típicos do python, como dicionários que podem ser facilmente renderizados em JSON, XML, entre outros.
Para compreender melhor, vamos analisar o funcionamento dessa conversão no projeto de uma escola que utiliza um modelo de cadastro de alunos, no código a seguir:
# app ‘escola’ no arquivo ‘models.py’
from django.db import models
class Aluno(models.Model):
nome = models.CharField(max_length = 30)
rg = models.CharField(max_length=9)
cpf = models.CharField(max_length=11)
data_nascimento = models.DateField()
def __str__(self):
return self.nome
Se realizarmos uma consulta ao banco de dados para recuperar todos os registros presentes na tabela correspondente a esse modelo de classe, temos a seguinte resposta:
Essa informação de <QuerySet [<Aluno: Lais>, <Aluno: Gui>, <Aluno: Ana>]>
nada mais é que a representação complexa de todos os objetos que foram guardados no banco de dados, retornados do modo que definimos no método __str__
do modelo.
Contudo, para tornar esses dados mais acessíveis e intercambiáveis, precisamos transformar esse objeto complexo em um tipo de dado do Python que seja facilmente serializado, especialmente quando lidamos com a transmissão de dados por meio de APIs ou a representação em formato JSON.
Para isso, criamos um serializer para esse modelo, estruturando o seguinte:
# app ‘escola’ no arquivo ‘serializers.py’
from rest_framework import serializers
from escola.models import Aluno
class AlunoSerializer(serializers.ModelSerializer):
class Meta:
model = Aluno
fields = ['id','nome','rg','cpf','data_nascimento']
Nesse caso, transformar o QuerySet em um tipo de dado Python significa que queremos uma representação mais simples dos dados, como em uma lista de dicionários ou uma lista de strings. Fazendo essa conversão no terminal, obtemos a seguinte resposta:
Agora, dados_serializados
é uma lista de dicionários que pode ser facilmente convertida em JSON para ser utilizada em APIs ou em outros contextos que exigem uma representação mais simples e universal dos dados.
Além disso, podemos utilizar o serializer para filtrar os dados que são importantes para serem adicionados na nossa API. No exemplo a seguir, alteramos a classe do serializer para receber todos os campos, com exceção do data_nascimento
e transformamos esses dados em um JSON:
Este processo de transformação é essencial para facilitar a comunicação entre sistemas heterogêneos e garantir a interoperabilidade dos dados. Mas além disso, o que faz o serializer ser tão essencial na criação de APIs com o Django Rest Framework?
A importância de serializer no DRF
Como vimos, os serializers permitem a transformação eficiente de objetos complexos, como modelos de banco de dados Django, em formatos facilmente transmitidos pela web, como JSON. Eles desempenham um papel crucial na representação dos dados e na comunicação entre o backend e o frontend.
Algumas características que tornam o serializer tão importante são:
Validação de dados
Ao receber dados por meio de solicitações, os serializers fornecem uma camada de validação. A validação inclui a verificação de tipos de dados, restrições de comprimento, integridade e qualquer lógica de validação personalizada definida por quem está desenvolvendo. Isso é vital para garantir a integridade dos dados e prevenir inconsistências no backend.
Facilidade de desserialização
Os serializers do DRF simplificam a desserialização de dados recebidos em objetos utilizáveis no backend, através da conversão de dados formatados (por exemplo, JSON) em objetos Python utilizáveis no backend. Isso é crucial para traduzir os dados recebidos em um formato manipulável no sistema.
Tratamento de relacionamentos e dados aninhados
Em casos de relacionamentos complexos ou dados aninhados, os serializers do DRF oferecem maneiras eficazes de lidar com essas estruturas de forma organizada. Isso é muito útil em situações em que os modelos têm associações complexas ou quando há necessidade de representar dados hierárquicos.
Flexibilidade e customização
Os Serializers do DRF oferecem um alto nível de flexibilidade, permitindo personalizar a serialização e desserialização conforme necessário. Isso inclui a capacidade de criar campos personalizados, validar dados com lógica específica do aplicativo e adaptar a representação dos dados para atender aos requisitos específicos da aplicação.
Representação padronizada
Os serializers do DRF permitem definir como os dados devem ser representados na saída da API. Isso garante uma consistência na estrutura da resposta, facilitando a compreensão e o consumo dos dados por parte dos clientes da API.
A capacidade dos serializers de transformar dados complexos em formatos interoperáveis não apenas facilita a representação padronizada e a validação eficaz, mas também desempenha um papel crucial na escolha entre os tipos de serializers a serem utilizados no projeto.
Tipos de serializer no DRF
No DRF há diversos tipos de serializers, sendo os dois principais: ModelSerializer
e Serializer
. Ambos são usados para definir como os dados são serializados e desserializados, mas têm propósitos ligeiramente diferentes.
ModelSerializer
O ModelSerializer
é um tipo de serializer especializado para interagir com modelos do Django. Ele simplifica muito o processo de criação de serializers para modelos, pois ele automaticamente infere muitos detalhes com base nos modelos.
No exemplo anterior, utilizamos o serializer do tipo Model, como podemos ver a seguir e podemos definir o atributo fields
com um valor especial 'all' para indicar que todos os campos do modelo devem ser usados:
from rest_framework import serializers
from escola.models import Aluno
class AlunoModelSerializer(serializers.ModelSerializer):
class Meta:
model = Aluno
fields = '__all__'
O ModelSerializer
automaticamente cria campos com base nos campos do modelo, trata relacionamentos automaticamente e fornece métodos padrão para criação e atualização .create()
e .update()
.
Serializer
Ao contrário do ModelSerializer
, que é otimizado para interagir diretamente com modelos do Django, o Serializer
é um tipo mais genérico que oferece maior controle manual sobre como os dados são serializados e desserializados. É útil para definir campos manualmente, lidar com lógica personalizada de validação ou quando está trabalhando com dados que não estão diretamente associados a modelos do Django.
Adaptando o exemplo anterior para utilizarmos esse novo tipo, fizemos o seguinte código:
from rest_framework import serializers
class AlunoSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
nome = serializers.CharField(max_length=30)
cpf = serializers.CharField(max_length=11)
rg = serializers.CharField(max_length=9)
data_nascimento = serializers.DateField()
Perceba que o Serializer
oferece maior flexibilidade, mas requer definição manual de todos os campos e lógica associada.
Além disso, é necessário fornecer implementações personalizadas para os métodos create e update. Esses métodos definem como os dados são tratados ao criar ou atualizar objetos no banco de dados, como complementado a seguir:
def create(self, validated_data):
return Aluno.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.nome = validated_data.get('nome', instance.nome)
instance.cpf = validated_data.get('cpf', instance.cpf)
instance.rg = validated_data.get('rg', instance.rg)
instance.data_nascimento = validated_data.get('data_nascimento', instance.data_nascimento)
instance.save()
return instance
Ambos os tipos de serializers fornecem funcionalidades para validar e processar dados recebidos, bem como transformá-los em formatos como JSON para serem enviados pela web. A escolha entre ModelSerializer
e Serializer
depende da complexidade do seu modelo e dos requisitos específicos de seu aplicativo. O ModelSerializer
é mais conveniente quando você está trabalhando com modelos do Django, enquanto o Serializer
oferece mais controle em situações mais personalizadas.
Você pode ler a documentação do serializer para escolher qual tipo se adequa mais ao projeto que você está desenvolvendo.
Conclusão
Ao combinar as possibilidades do Django Rest Framework com a flexibilidade e eficiência dos serializers, as pessoas desenvolvedoras podem criar APIs robustas que atendem aos mais altos padrões de qualidade e desempenho.
Afinal, os serializers no DRF possuem a capacidade de simplificar e aprimorar esse processo de desenvolvimento de APIs. Eles são componentes essenciais que facilitam a manipulação eficiente de dados, garantindo a consistência na representação, validação e transmissão de informações entre sistemas diversos.
Com os serializers do DRF, devs podem criar APIs poderosas e escaláveis, promovendo uma comunicação eficiente e coesa entre o backend e o frontend de suas aplicações.
Que tal dar um mergulho ainda mais profundo? Deixamos aqui algumas referências para te ajudar nos seus estudos de Django Rest Framework:
- Artigo: O que é Python? História, Sintaxe e um Guia para iniciar na Linguagem
- Artigo: Django: o que é, para que serve e um Guia desse framework Python
- Artigo: Django e Django Rest: Diferenças e aplicações
- Artigo: Django Rest Framework: Versionamento
- Artigo: Django: QuerySets e ORM
- Site do Django
- Site do Django Rest Framework
- What is Django Serializer (vídeo em inglês)