Introdução
Neste tutorial, vamos explorar a construção de microserviços utilizando Scala, com foco nas tecnologias Akka e Play Framework, além da implementação de contêineres Docker para facilitar a escalabilidade e otimização do desenvolvimento. A arquitetura de microserviços permite que sistemas complexos sejam divididos em partes independentes, aumentando a agilidade e a eficiência das equipes de desenvolvimento. Vamos passar por todas as etapas necessárias, desde a configuração do ambiente até o desenvolvimento de uma aplicação completa que será empacotada em um contêiner Docker. Este guia é direcionado a desenvolvedores que desejam compreender como construir microserviços de forma prática e eficaz.
Etapas
Configuração do Ambiente de Desenvolvimento
Certifique-se de ter o JDK (Java Development Kit) e o SBT (Scala Build Tool) instalados em sua máquina. Além disso, instale o Docker para possibilitar a contêinerização da aplicação. Verifique as versões instaladas usando os comandos `java -version`, `sbt sbtVersion`, e `docker –version`. Se algum deles não estiver instalado, siga as instruções oficiais disponíveis nos sites das respectivas ferramentas.
commands# Verificar versões instaladas
java -version
sbt sbtVersion
docker --versionCriação do Projeto Play Framework
Utilize o SBT para criar um novo projeto Play Framework. Abra o terminal e execute o comando: `sbt new playframework/play-scala-seed.g8`. Quando solicitado, forneça um nome para o projeto e as opções desejadas. Este comando configurará a estrutura básica do projeto com todas as dependências necessárias.
commandssbt new playframework/play-scala-seed.g8
Implementação do Serviço com Akka
Adicione a dependência do Akka no arquivo `build.sbt` para permitir a criação de atores e gerenciamento assíncrono. Após adicionar a dependência, implemente uma classe de ator simples que responda a mensagens.
build.sbtlibraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.6.14"
MyActor.scalapackage actors import akka.actor.{Actor, Props} class MyActor extends Actor { def receive = { case message: String => sender() ! s"Mensagem recebida: $message" } } object MyActor { def props: Props = Props[MyActor]() }
Criação do Controlador
Implemente um controlador no Play Framework que irá utilizar o Akka para processar requisições HTTP. O controlador deve interagir com o ator criado anteriormente.
MyController.scalapackage controllers import javax.inject._ import play.api.mvc._ import akka.actor.{ActorSystem, Props} import actors.MyActor import akka.pattern.ask import akka.util.Timeout import scala.concurrent.duration._nimport scala.concurrent.{Await, Future} @Singleton class MyController @Inject()(cc: ControllerComponents)(implicit system: ActorSystem) extends AbstractController(cc) { implicit val timeout: Timeout = Timeout(5.seconds) val myActor = system.actorOf(MyActor.props) def sendMessage(message: String) = Action.async { val future: Future[String] = (myActor ? message).mapTo[String] future.map { response => Ok(response) } } }
Configuração do Docker
Crie um arquivo `Dockerfile` para empacotar sua aplicação Play Framework em um contêiner Docker. Isso garantirá que sua aplicação seja executada em um ambiente controlado.
DockerfileFROM openjdk:11-jre-slim COPY target/universal/stage /app WORKDIR /app RUN bin/myproject -Dplay.http.secret.key=secret CMD ["bin/myproject", "-Dplay.http.port=9000"]
Construção e Execução do Contêiner
Utilize o Docker para construir e executar seu contêiner. No terminal, execute o comando `docker build -t my-play-app .` e, em seguida, `docker run -p 9000:9000 my-play-app` para iniciar a aplicação em um contêiner.
commandsdocker build -t my-play-app .
docker run -p 9000:9000 my-play-appTestando a Aplicação
Utilize ferramentas como Postman ou cURL para testar a funcionalidade da sua aplicação. Verifique se o seu controlador responde corretamente às requisições enviadas.
curl_examples# Enviar uma mensagem para o ator
curl -X GET http://localhost:9000/sendMessage?message=OláImplementação de Testes Unitários
Crie testes unitários para o seu serviço utilizando o framework de testes ScalaTest. Certifique-se de cobrir as funcionalidades principais na lógica de negócios.
MyActorSpec.scalapackage actors import akka.actor.ActorSystem import akka.testkit.TestKit import akka.pattern.ask import akka.util.Timeout import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} import scala.concurrent.duration._ import scala.concurrent.Await class MyActorSpec extends TestKit(ActorSystem("MyActorSpec")) with WordSpecLike with Matchers with BeforeAndAfterAll { implicit val timeout: Timeout = Timeout(5.seconds) val myActor = system.actorOf(MyActor.props) "MyActor" should { "respond to messages" in { val future = myActor ? "Teste" val response = Await.result(future, timeout.duration) response shouldEqual "Mensagem recebida: Teste" } } override def afterAll(): Unit = { TestKit.shutdownActorSystem(system) } }
Executando a Aplicação e Testes
Compile e execute a aplicação utilizando SBT e execute os testes unitários. Utilize os comandos `sbt run` para iniciar a aplicação e `sbt test` para rodar os testes.
commands# Compilar e executar a aplicação
sbt run
# Executar os testes unitários
sbt test
Conclusão
Neste tutorial, você aprendeu a construir um microserviço utilizando Scala com os frameworks Akka e Play, além de como empacotá-lo em um contêiner Docker. Vimos todo o processo desde a configuração do ambiente de desenvolvimento até a criação de um controlador e testes unitários. Com essas habilidades, você está preparado para explorar soluções de arquitetura de microserviços e implementar aplicações escaláveis e eficientes no mercado de desenvolvimento de software.