Como seu sistema envia email?

Mandar email é uma tarefa bem rotineira em nossos projetos. Mandamos email de boas vindas quando um novo usuário se cadastra, email para recuperar senha etc. Uma coisa que geralmente todas essas features tem em comum, é que o email deve ser enviado em HTML.

Existem alguns projetos para facilitar a escrita do template do email e carregá-lo dentro do projeto, o Freemarker é um desses. Mais antigamente, o Velocity também era uma opção muito usada no mercado. O objetivo do post é justamente mostrar que podemos implementar essas features com algo que já está presente no seu projeto, sem a necessidade de aprender uma nova tecnologia ou adicionar uma dependência nova no seu projeto.

Pensando no código que você escreveria com o Freemarker, seria algo mais ou menos assim:

		@Controller
		public class HomeController {
		
			@PostMapping("/usuario")
			public String novoUsuario(Usuario usuario) {
		
				usuarioDao.salva(usuario);
  
				HtmlEmail email = new HtmlEmail();
				Freemarker template = new Freemarker();
				String body = template.resolve(HomeController.class.getResourceAsStream("/boasvidas.ftl"),usuario);
				email.setBody(body);
				...
			}
		}

A ideia é que agora a gente tem que carregar o HTML de uma outra forma. Pensando que nosso projeto é web, meio que já temos isso pronto. Dê uma olhada no controller que temos abaixo:

		@Controller
		public class TemplateController {
		
			@GetMapping("/template/boas-vindas")
			public String boasVindas(Integer idUsuario,Model model) {
				Usuario usuario = usuarioDao.carrega(idUsuario);
				model.addAttribute("usuario", usuario);
				return "templates/boasvindas";
			}
		}

Este é um controller que serve como gerador de HTML para emails que precisam ser enviados pelo sistema. Agora só precisamos acessar o endereço no momento de envio dos emails.

		@Controller
		public class HomeController {
		
			@GetMapping("/")
			public String novoUsuario(Usuario usuario) {
				RestTemplate restTemplate = new RestTemplate();
				ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8080/template/boas-vindas/"+usuario.getId(), String.class);
				String body = entity.getBody();
				
				HtmlEmail email = new HtmlEmail();
				email.setBody(body);
				
				return "home/index";
			}
		}

Dessa forma resolvemos o problema de geração do conteúdo do email. Como o acesso é feito via localhost, não interfere quase nada no desempenho. Além disso você pode continuar escrevendo seu HTML da mesma maneira que sempre escreveu, o que também é um bom ganho.

O post em si não tem muito haver com o universo do Spring, mas achei legal compartilhar porque é uma solução que tenho usado bastante nos projetos e acho que tem funcionado bem. E aí, o que achou? Muita gambiarra?

4 thoughts on “Como seu sistema envia email?

  1. Oi Alberto,

    Bem bolado a idéia, realmente funciona sem necessidade de outro framework, como FreeMarker ou Velocity. Ou seja, dá pra se virar com o que já temos na aplicação, não é mesmo?

    Um detalhe, em aplicações pequenas e/ou com pouco acesso a essa feature não há qualquer problema, mas se for diferente disso o ideal é deixar o template ser processado na mesma requisição/thread ou jogar numa fila para processamento posterior, afinal, há um custo considerável em abrir conexão http, fazer handshake, request-response, abrir nova thread no mesmo servidor etc.

    Liked by 1 person

  2. Opa Rafael, exato, a ideia pode ser aproveitada para qualquer aplicação. Em relação ao custo da requisição, acho que eu esperaria ela virar um problema para o sistema se preocupar, mesmo em aplicações maiores. Claro que gerar um email vai concorrer com uma requisição normal, mas esperaria um pouco para ver se isso realmente acarretaria em algum problema.

    Like

    • Acabaste de criar um microsserviço de renderização de HTML! 😀

      Agora sério: concordo com o que o Rafael disse. Trocar uma invocação intra-thread por inter-processos com o overhead do HTTP não parece uma boa… E depender de um Velocity ou Freemarker não é lá tão ruim, vai…

      Mas você me fez pensar: não daria pra usar a própria JSP para renderizar o email?

      Like

Leave a comment