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

  1. 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 --version

  2. Criaçã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.

    commands
    sbt new playframework/play-scala-seed.g8

  3. 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.sbt
    libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.6.14"

    MyActor.scala
    package 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]()
    }

  4. 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.scala
    package 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)
        }
      }
    }

  5. 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.

    Dockerfile
    FROM 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"]

  6. 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.

    commands
    docker build -t my-play-app .
    docker run -p 9000:9000 my-play-app

  7. Testando 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á

  8. 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.scala
    package 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)
      }
    }

  9. 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.

Hashtags

#Scala #Akka #PlayFramework #Docker #Microserviços #DesenvolvimentoDeSoftware