Dependências


O que são dependências?

Uma dependência é um componente de software do qual outra parte do código depende para funcionar corretamente. São normalmente utilizadas para adicionar características e funcionalidades sem a necessidade de escrever código do zero. Em essência, as dependências são códigos reutilizáveis encontrados em pacotes ou módulos de bibliotecas para os quais o seu código faz chamadas.

Exemplo simplificado:

  • Programa A: Precisa de uma função que não possui nativamente
  • Programa B: Contém a função necessária
  • Relacionamento: O Programa A faz uma chamada ao Programa B para utilizar essa função
  • Resultado: O Programa A é o dependente e o Programa B é a dependência

Benefícios de usar dependências

  • Eficiência: O processo de desenvolvimento torna-se mais rápido e eficiente
  • Velocidade: É possível entregar software mais rapidamente com base em trabalhos anteriores
  • Funcionalidades: As aplicações podem ter mais recursos e capacidades
  • Otimização: A funcionalidade fornecida pode ter um desempenho melhor do que uma implementação nativa
  • Reutilização: Elimina a necessidade de escrever código do zero

Riscos e desafios

Segurança e estabilidade

  • Descarregar e utilizar código da Internet pode expor seu software a:
    • Vulnerabilidades
    • Bugs
    • Outras falhas de segurança

Riscos em produção

Implementar dependências incompatíveis, desatualizadas ou ausentes pode causar:

  • Degradação do desempenho dos servidores
  • Falhas em sistemas de produção
  • Fuga de dados devido a vulnerabilidades
  • Comprometimento dos dados dos clientes
  • Danos à reputação da empresa (perda de negócios ou multas)

Questões de licenciamento

  • Esteja ciente dos requisitos de licença para as dependências utilizadas
  • Use o tipo correto de licenciamento para o seu projeto
  • Certifique-se de que não há código não licenciado na sua aplicação

Melhores práticas

Análise prévia

Antes de implementar uma dependência, é recomendável examiná-la completamente:

  1. Design: Verifique se a API é bem projetada e documentada
  2. Qualidade: Avalie o código quanto a comportamentos indesejados e problemas semânticos
  3. Testes: Teste a funcionalidade básica e procure possíveis falhas
  4. Depuração: Verifique o rastreador de problemas para issues abertas e relatórios de erros
  5. Manutenção: Reveja o histórico de commits para correções de bugs e melhorias contínuas
    • Evite dependências não atualizadas há mais de um ano
  6. Adoção: Verifique se a dependência é amplamente utilizada (dependências raramente usadas podem ser abandonadas)
  7. Segurança: Procure pontos fracos e vulnerabilidades que permitam entradas maliciosas

Gestão de dependências

  • Utilize ferramentas de gestão de dependências para:
    • Gerenciar downloads
    • Acompanhar atualizações de versões
    • Listar todas as dependências diretas e indiretas

Dependências indiretas

Uma dependência que depende de outra dependência não é necessariamente problemática, mas apresenta desafios adicionais:

  • Problemas em dependências indiretas podem impactar seu código
  • É importante inspecionar todas as dependências indiretas
  • Ao atualizar dependências, esteja atento a novas dependências indiretas

Exemplo prático: Flask

O Flask é uma framework web escrita em Python que fornece ferramentas e bibliotecas para a criação de aplicações web.

Organizações que utilizam Flask:

  • LinkedIn
  • Pinterest

Dependências do Flask:

  • Werkzeug: Interface de gateway de servidor web
  • Jinja: Linguagem de template para renderizar páginas web
  • MarkupSafe: Dependência de segurança para entrada não confiável
  • ItsDangerous: Dependência para integridade de dados segura
  • Click: Framework para escrever aplicações de linha de comando

Exemplo de código: Utilizando a dependência ItsDangerous

from itsdangerous import URLSafeSerializer

# Instancia o serializador com uma chave secreta
serializer = URLSafeSerializer('chave-secreta', salt='auth')

# Gera um token com os dados que queremos serializar
token = serializer.dumps({'id': 5, 'nome': "alice"})

# O token pode ser enviado com segurança para outro serviço
# ou armazenado para uso posterior

# Para descriptografar o token:
dados = serializer.loads(token)
print(dados['nome'])  # Saída: alice

Este exemplo mostra como gerar um token seguro para transmitir informações de conta entre requisições web.

Resumo

  • Uma dependência é um componente de código do qual outra parte depende para funcionar
  • As dependências adicionam recursos e funcionalidades sem a necessidade de escrevê-los do zero
  • Elas podem acelerar o desenvolvimento e economizar recursos
  • Dependências devem ser cuidadosamente analisadas antes da implementação
  • Use gerenciadores de dependências para listar e inspecionar todas as dependências
  • Uma dependência pode ter suas próprias dependências (dependências indiretas)
  • O Flask é um exemplo de framework que fornece ferramentas e bibliotecas, tendo suas próprias dependências