So retorno e o que isso realmente implica no dia a dia
Existe um conceito que aparece com frequência em discussões técnicas sobre APIs e design de software, especialmente quando se fala em REST. A tradução literal do inglês "so return" para o português seria algo como "só retorno" ou "só regresso", dependendo da região. No Brasil, o mais comum é ouvir "so retorno". Mas o que isso significa na prática, fora dos livros? A ideia central é simples: uma operação deve devolver apenas o resultado final, sem efeitos colaterais, sem logs invasivos, sem modificar estado global invisível. Parece bobo falar disso, mas é onde muita coisa dá errado.
O que significa só regresso na prática técnica
Quando dizemos que uma função ou endpoint segue o principio de so retorno, estamos dizendo que ela recebe uma entrada, processa, e devolve uma saída previsivel. Nada mais. Se você chama a mesma funcao com os mesmos argumentos, o resultado sera sempre igual. Sem excecoes. Isso se conecta diretamente com o que chamamos de pureza funcional. Uma funcao pura não tem side effects. Ela nao grava em arquivo, nao dispara email, nao altera variavel global. Ela apenas calcula e devolve.
No contexto de APIs REST, isso se traduz em endpoints que retornam dados estruturados, preferencialmente em JSON, e que seguem metodos HTTP de forma adequada. GET retorna, POST cria e retorna o recurso criado, DELETE remove e retorna status, etc. A confusao começa quando as pessoas misturam tudo.
Como implementar so retorno corretamente
O primeiro passo e separar o que e comportamento do que e apresentacao. Se voce esta escrevendo uma funcao em Python, por exemplo, ela pode olhar assim: def calcular_descricao(preco, desconto):
if desconto >= 0 and desconto <= 100: return preco * (1 - desconto / 100)
raise ValueError("Desconto invalido") Essa funcao e pura. Ela recebe dois valores, valida, calcula e devolve. Nao imprime nada na tela, nao grava em banco, nao envia nada a lugar algum. O retorno e tudo.
O problema e que na vida real as coisas nunca sao tao limpas. Voce vai precisar persistir aquele dado. VAI precisar logar algum erro. A solusao e nao colocar isso dentro da funcao principal. Use um padrao de responsabilidade em cadeia. A funcao pura faz o calculo. Outro modulo cuida do que fazer com o resultado. Em arquiteturas maiores, isso se chama segregacao de preocupacoes. E um conceito basico que muita gente esquece porque parece trabalho extra no comeco. Mas economiza horas de debug depois.
O erro classico: confundir retorno com efeito colateral
Um erro extremamente comum, que eu vi acontecer repetidamente em projetos reais, e transformar uma operacao que deveria ser apenas um calculo em uma funcao que faz varias coisas ao mesmo tempo. A funcao recebe um pedido, calcula o valor, salva no banco, gera um PDF, envia por email, e ai sim retorna algo. Isso quebra todos os principios de so retorno. A funcao deixou de ser previsivel. Ela depende de estado externo (conexao com banco, servidor de email). Se algo falhar no meio do caminho, voce nunca sabe exatamente o que aconteceu só olhando o retorno.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Minha solucao aqui e dividir em etapas claras. Crie uma classe ou funcao responsavel apenas pelo calculo. Crie outra responsavel pela persistencia. E uma terceira para notificacoes. Cada uma com seu proprio escopo. Depois, na camada de aplicacao, voce orquestra tudo. Um detalhe importante: o retorno deve ser tipado quando possivel. Em linguagens como TypeScript ou com annotations em Python, voce deixa explicito o que a funcao devolve. Isso evita que quem for usar seu codigo tenha que adivinhar.
Aplicando o conceito em APIs REST
Se voce esta construindo uma API, o principio de so retorno se reflete diretamente nos codigos de status HTTP e no corpo das respostas. Um endpoint bem comportado nunca retorna JSON errados para o metodo errado. Se e um GET, voce so pega dados. Se e um POST, voce cria e retorna o recurso com status 201. Aqui vai uma dica que poucas pessoas mencionam: o corpo da resposta deve conter apenas o necessario. Se um cliente pede uma lista de produtos, nao retorne todos os campos de cada produto. Retorne os campos que fazem sentido para aquele contexto. Use DTOs (Data Transfer Objects) para isso. Isso e parte do compromisso com o so retorno tambem.
Outro ponto frequentemente ignorado e o tratamento de erros. Quando algo da errado, o retorno deve ser claro e padronizado. Um objeto com campos como code, message e timestamp e muito mais util do que uma mensagem solta em texto. Isso permite que o cliente trate o erro de forma programatica.
Um caso real que quase me custou semanas
Eu trabalhei em um projeto onde um endpoint de consulta retornava dados de usuarios, mas internamente a funcao tambem atualizava um campo de "ultimo acesso" no banco. O problema era que esse campo era atualizado a cada requisição, inclusive por health checks e monitoramentos automatizados. O log do banco crescia de forma explosiva, e os indices de atualizacao sobrecarregavam o servidor. A solucao foi simples, mas demorei para perceber: removi a atualizacao do campo da funcao de consulta. A atualizacao passou a acontecer apenas em um middleware especifico, separado do fluxo de leitura. O retorno da API ficou puro, e o sistema todo estabilizou.
O aprendizado aqui e que "so retorno" nao significa apenas o que a funcao devolve. Significa tambem o que ela NAO faz. E essa negacao e mais importante do que opositive muitas vezes.
Falhas possiveis e quando o conceito nao se aplica
Este principio tem limitacoes claras. Ele nao funciona bem em contextos onde o efeito colateral e o objetivo principal. Se voce esta construindo um batch processor que deve escrever arquivos, enviar emails e atualizar tabelas, forcar pureza excessiva vai tornar o codigo mais complexo do que necessario. Nesses casos, use orquestradores claros em vez de funcoes puras isoladas. Tambem nao adianta muito em ambientes com estado compartilhado agressivo, como certas arquiteturas monoliticas legado. La, a separacao de responsabilidade muitas vezes ja esta comprometida em varios niveis, e impor so retorno em um unico ponto pode criar mais problemas do que solucoes.
Uma alternativa quando o principio nao se aplica e usar o que chamamos de monad de efeito, como IO em Haskell ou Task em F#. Eles permitem que voce modele operações com side effects de forma controlada, mantendo a previsibilidade sem eliminar os efeitos completamente.
Resumo direto do que importa
Entender o que significa so retorno é entender que cada parte do seu sistema deve ter uma responsabilidade clara e isolada. Funcoes calculam e devolvem. Endpoints retornam dados e status. Handlers executam ações e comunicam resultados. Quando voce mistura isso tudo, o codigo vira uma caixa preta que todo mundo odeia manter. Na prática, siga estes pontos: mantenha funcoes puras o máximo possível, separe lógica de negócio de infraestrutura, padronize respostas de erro, evite efeitos colaterais em operações de leitura, e teste cada componente isoladamente antes de orquestrar. Se alguém mencionar "só regresso" ou "so return" em uma reunião tecnica, saiba exatamente do que se trata e pergunte sobre os casos em que isso não se aplica. As respostas vão revelar muito sobre a maturidade técnica do time.
O conceito em si não é complexo, mas a disciplina para aplica-lo de verdade é o que separa projetos sustentaveis de projetos que viram dor de cabeca perpetua. E isso vale tanto para funcoes pequenas quanto para arquiteturas inteiras.