[Análise] Django é bom para backend?
Olá, esse artigo foi criado como uma forma de análise do framework Django na visão de um desenvolvedor sem experiência em Python. A idéia é levantar uma discursão sobre o framework que já é bem estável no mercado, mas não apenas no nível curso de internet. O foco será no Django REST Framework, não pretendo trabalhar com HTML nesse projeto.
Quem eu sou
Dev Flutter há 4 anos, já estagiei como dev backend C# por um ano antes de migrar para a área de mobile. Já fiz pequenas APIs com Express, Ktor e C#, mas todas de estudo e nenhuma muito complexa
Introdução
O Django REST Framework (DRF) já é um framework estável e bem utilizado no mercado de programação, por utilizar Python como linguagem e tendo um foco em abstração ele ficou bem popular, sendo um dos mais famosos frameworks backend para Python, lado a lado com Flask e FastAPI.
Meu nome é Pedro e tenho trabalhado com programação há alguns anos, suficiente para reconhecer que nenhum cursinho de internet vai trazer uma experiência de trabalhar para uma empresa, trabalhar com diversas classes, camadas de validação e lógica de negócio, o projeto criado serviria perto de um MVP (Mínimo Produto Viável) para um projeto em produção até onde entendo.
O Projeto
Sistema de gestão de inventário. Teremos 3 entidades principais: User (tendo nome, email, senha e indicador se é administrador ou não), Departament (contendo também o usuário responsável por ele), Item (a coisa a ser armazenada naquele departamento, tipo uma cadeira ou mesa) e também temos uma entidade “de suporte” que é a MovingHistory, que deve armazenar o registro de uma mudança de um item entre departamentos. Essa última só é possível criar, mas seus dados serão retornados ao se consultar o item movido.
A arquitetura (será inclusive um dos tópicos a serem discutidos) seguirá um padrão de MVC (Model-View-Controller), mantendo o formato de pastas como a seguir:
Existem ainda todas as classes e arquivos de configuração do Django, mas não é necessário mostrar no diagrama.
Não temos o controller de Item nem o modelo User. Será explicado a seguir
O framework e desenvolvendo com ele
O Django É um framework. Meio óbvio, mas quero dizer que ele segue um fluxo diferente do que se está acostumado com outras ferramentas para backend, quando mexi com ExpressJs e Ktor, eles tinham uma relação mais de biblioteca do que de framework com o código. Como assim? A biblioteca ela te entrega algo específico, ela resolve uma necessidade específica, por exemplo: te permite publicar as rotas, configurações de CORS e outras coisas específicas com a parte da comunicação externa do programa, mas um framework ele te entrega algo muito maior, como ORM, conexão com banco mais simples, praticidade para publicação, etc, além do que a biblioteca já entrega, o mais perto que vi foi com C# com o EntityFramework
Ponto positivo é que ele faz muita coisa, ponto negativo é que ele faz coisa demais. Vai ficar mais claro no final.
Além das configurações já prontas e rápidas que você pode fazer no settings.py
, ele também trás o chamado ViewSet, que no final é uma abstração para um CRUD. Você define a entidade e o serializer (classe responsável por fazer a conversão modelo -> JSON e JSON -> modelo), faz o chamado no urls.py
e pronto, você tem TODOS os endpoints prontos, até PATCH e GET/id, além de também trazer uma UI simples para caso não queira configurar o swagger no projeto.
O propósito de criar um Controller para cada entidade seria justamente para servir de camada de validação e regra de negócio. No caso de User, trabalhei muito mais “manualmente” devido a ser a primeira entidade trabalhada no inicio do projeto, mas passei a não utilizar um controller para Item, devido que não havia nenhuma regra específica para essa entidade e devido a abstração dada pela ViewSet, não tornou necessário reescrever as funções do CRUD de Item. Essa abstração também me fez permitir sobrescrever apenas o que achei interessante, como é o caso de Department, que tem uma ViewSet, mas ainda sim tem um controller. Cada entidade eu abordei de uma forma diferente para ver como o framework funcionava.
Outra vantagem do Django é que ele abstrai todo o processo de configuração de autenticação tendo o modelo de usuário pronto dentro do sistema. Por regra você precisa ter 1 superusuário (administrador), mas também permite que possamos criar endpoints de criação, update e delete dos usuários do Django, tanto administradores como usuários normais. Ele já cria o modelo e o armazenamento das senhas (com hash e tudo), além da rota de login que basta configurar no urls.py
Como falei de autenticação, você pode definir a regra (BasicAuthentication, TokenAuthentication, etc) no próprio settings.py
. Para seguir o padrão que eu estava acostumado, ativei a autenticação por Bearer Token, o que também não foi difícil, só criei uma classe seguindo um tutorial e no arquivo de configurações apontei pra o arquivo que eu tinha criado, além de deixar por padrão a exigência de autenticação para usar o sistema, que ele valida automaticamente.
Os cursos que vi de Django (terminei a formação em Django 3 da alura + playlists do youtube) não mostravam um formato mais complexo. Funcionava, mas era muito mais fácil ensinar a parte “superficial”, isso é um problema que vejo em todos os cursos de programação. Nenhum te ensina um sistema complexo (até porque da trabalho e não venderia tanto).
Conclusão
O DRF possui muitas funcionalidades e várias formas de implementar a mesma coisa. As classes ViewSet ajudam muito ao criar um CRUD simples, então é fácil implementar algo rápido (como a classe ItemView), mas não é tão intuitivo quando precisamos implementar algumas regras, limitar as ações (como fiz na classe MovingHistoryView) ou adicionar uma camada de validação (como usei os Controllers).
Embora pareça ser um ponto negativo, não é. É realmente interessante que o DRF seja flexível o suficiente para implementar todos os endpoints de CRUD sem precisar se preocupar com cada rota, além de ter formas de implementar lógica "manualmente", é diferente do que já fiz em um API REST em C#, mas ainda assim é uma maneira que funciona.
Sobre o padrão MVC, tentei usar ele sem criar classes desnecessárias, por isso a classe ItemView não tem uma classe ItemController. O padrão em si não é desperdiçado, mas ainda é difícil não usar os atalhos que o DRF oferece.
Se esse sistema crescer, eu criaria modelos externos e classes de Repositório. Os modelos externos eu usaria quando os dados estão na camada de View e as classes de Repositório seriam úteis ao salvar os dados no banco de dados (com uma conversão de modelos externos para modelos de domínio).
Continuando sobre os padrões de projeto, usei o padrão Result, similar ao Either, usando o pacote returns, ao obter o resultado do Controller. Provavelmente há uma maneira melhor de codificar isso, mas eu sou um pouco novato no universo Python.
Minha conclusão é: que eu preciso aprender mais. Django é sim um bom framework backend e vale a pena investir mais tempo, eu realmente gostei do framework e como eu posso criar coisas rápido com ele se eu tiver experiência. Um desvantagem é que tudo o que eu queria fazer eu tinha que pesquisar na documentação, as classes e o código não explicam muito, dar um ctrl+click não explica muito. Usaria ainda ele em um projeto? Sim, mas em um MVP. Meu próximo alvo é o Flask.
Mas e vocês? Já mexerem com Django? Concordam ou discordam do que já comentei?
O link do código é esse daqui https://github.com/arcbueno/rheoli-cyfoeth-backend-django