Introdução ao Micronaut Framework

Introdução ao Micronaut Framework

1. O que é micronauta

Micronaut é uma estrutura baseada em JVM para a construção de aplicativos leves e modulares. Desenvolvido pela OCI, a mesma empresa que criou a Grails,Micronaut is the latest framework designed to make creating microservices quick and easy.

Embora o Micronaut contenha alguns recursos semelhantes aos frameworks existentes, como o Spring, também possui alguns novos recursos que o diferenciam. E com suporte para Java, Groovy e Kotlin, oferece várias maneiras de criar aplicativos.

2. Principais características

Um dos recursos mais interessantes do Micronaut é o mecanismo de injeção de dependência de tempo de compilação. A maioria das estruturas usa reflexão e proxies para executar a injeção de dependência em tempo de execução. Micronaut, however, builds its dependency injection data at compile time. O resultado é uma inicialização mais rápida do aplicativo e pegadas de memória menores.

Another feature is its first class support for reactive programming, for both clients and servers. A escolha de uma implementação reativa específica é deixada para o desenvolvedor, já que RxJava e Project Reactor são suportados.

O Micronaut também possui vários recursos que o tornam uma excelente estrutura para o desenvolvimento de aplicativos nativos da nuvem. It supports multiple service discovery tools such as Eureka and Consul, and also works with different distributed tracing systems such as Zipkin and Jaeger.

Ele também fornece suporte para a criação de funções lambda da AWS, facilitando a criação de aplicativos sem servidor.

3. Começando

A maneira mais fácil de começar é usandoSDKMAN:

> sdk install micronaut 1.0.0.RC2

Isso instala todos os arquivos binários que precisamos para construir, testar e implantar aplicativos Micronaut. Ele também fornece a ferramenta CLI do Micronaut, que permite iniciar facilmente novos projetos.

Os artefatos binários também estão disponíveis emSonatypeeGitHub.

Nas seções a seguir, veremos alguns recursos da estrutura.

4. Injeção de dependência

Como mencionado anteriormente, o Micronaut lida com a injeção de dependência em tempo de compilação, que é diferente da maioria dos contêineres de IoC.

No entanto, ele aindafully supports JSR-330 annotations, portanto, trabalhar com beans é semelhante a outros frameworks IoC.

Para conectar automaticamente um bean em nosso código, usamos@Inject:

@Inject
private EmployeeService service;

A anotação@Inject funciona exatamente como@Autowired e pode ser usada em campos, métodos, construtores e parâmetros.

Por padrão, todos os beans têm o escopo definido como um protótipo. Podemos criar beans singleton rapidamente usando@Singleton. Se várias classes implementarem a mesma interface de bean,@Primary pode ser usado para decompô-los:

@Primary
@Singleton
public class BlueCar implements Car {}

A anotação@Requires pode ser usada quando os beans são opcionais ou apenas para realizar a autowiring quando certas condições são atendidas.

Nesse sentido, ele se comporta de maneira muito semelhante às anotações do Spring Boot@Conditional:

@Singleton
@Requires(beans = DataSource.class)
@Requires(property = "enabled")
@Requires(missingBeans = EmployeeService)
@Requires(sdk = Sdk.JAVA, value = "1.8")
public class JdbcEmployeeService implements EmployeeService {}

5. Construindo um servidor HTTP

Agora vamos ver como criar um aplicativo de servidor HTTP simples. Para começar, usaremos SDKMAN para criar um projeto:

> mn create-app hello-world-server -build maven

Isso criará um novo projeto Java usando Maven em um diretório chamadohello-world-server.. Dentro desse diretório, encontraremos o código-fonte do nosso aplicativo principal, o arquivo Maven POM e outros arquivos de suporte para o projeto.

O aplicativo padrão que é muito simples:

public class ServerApplication {
    public static void main(String[] args) {
        Micronaut.run(ServerApplication.class);
    }
}

5.1. Bloqueando HTTP

Por si só, este aplicativo não fará muito. Vamos adicionar um controlador que tem dois pontos de extremidade. Ambos retornarão uma saudação, mas um usará o verbo HTTPGET e o outro usaráPOST:

@Controller("/greet")
public class GreetController {

    @Inject
    private GreetingService greetingService;

    @Get("/{name}")
    public String greet(String name) {
        return greetingService.getGreeting() + name;
    }

    @Post(value = "/{name}", consumes = MediaType.TEXT_PLAIN)
    public String setGreeting(@Body String name) {
        return greetingService.getGreeting() + name;
    }
}

5.2. IO reativo

Por padrão, o Micronaut implementará esses pontos de extremidade usando E / S de bloqueio tradicional. No entanto,we can quickly implement non-blocking endpoints by merely changing the return type to any reactive non-blocking type.

Por exemplo, com RxJava podemos usarObservable. Da mesma forma, ao usar o Reactor, podemos retornarMono ouFlux tipos de dados:

@Get("/{name}")
public Mono greet(String name) {
    return Mono.just(greetingService.getGreeting() + name);
}

Para terminais de bloqueio e não bloqueio, o Netty é o servidor subjacente usado para lidar com solicitações HTTP.

Normalmente, as solicitações são tratadas no conjunto de encadeamentos de E / S principal criado na inicialização, tornando-os bloqueados.

No entanto, quando um tipo de dados sem bloqueio é retornado de um ponto de extremidade do controlador, o Micronaut usa o segmento de loop de eventos Netty, tornando a solicitação inteira sem bloqueio.

6. Construindo um cliente HTTP

Agora vamos construir um cliente para consumir os endpoints que acabamos de criar. O Micronaut fornece duas maneiras de criar clientes HTTP:

  • Um cliente HTTP declarativo

  • Um cliente HTTP programático

6.1 Declarative HTTP Client

A primeira e mais rápida maneira de criar é usando uma abordagem declarativa:

@Client("/greet")
public interface GreetingClient {
    @Get("/{name}")
    String greet(String name);
}

Observe comowe don’t implement any code to call our service. Em vez disso, o Micronaut entende como chamar o serviço a partir da assinatura do método e das anotações que fornecemos.

Para testar esse cliente, podemos criar um teste JUnit que usa a API do servidor incorporado para executar uma instância incorporada do nosso servidor:

public class GreetingClientTest {
    private EmbeddedServer server;
    private GreetingClient client;

    @Before
    public void setup() {
        server = ApplicationContext.run(EmbeddedServer.class);
        client = server.getApplicationContext().getBean(GreetingClient.class);
    }

    @After
    public void cleanup() {
        server.stop();
    }

    @Test
    public void testGreeting() {
        assertEquals(client.greet("Mike"), "Hello Mike");
    }
}

6.2. Cliente HTTP programático

Também temos a opção de escrever um cliente mais tradicional se precisarmos de mais controle sobre seu comportamento e implementação:

@Singleton
public class ConcreteGreetingClient {
   private RxHttpClient httpClient;

   public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) {
      this.httpClient = httpClient;
   }

   public String greet(String name) {
      HttpRequest req = HttpRequest.GET("/greet/" + name);
      return httpClient.retrieve(req).blockingFirst();
   }

   public Single greetAsync(String name) {
      HttpRequest req = HttpRequest.GET("/async/greet/" + name);
      return httpClient.retrieve(req).first("An error as occurred");
   }
}

O cliente HTTP padrão usa RxJava, portanto, pode trabalhar facilmente com chamadas bloqueadas ou não bloqueadas.

7. CLI do Micronaut

Já vimos a ferramenta Micronaut CLI em ação acima, quando a usamos para criar nosso projeto de amostra.

No nosso caso, criamos um aplicativo independente, mas ele também possui vários outros recursos.

7.1. Projetos de federação

In Micronaut, a federation is just a group of standalone applications that live under the same directory. Usando federações, podemos facilmente gerenciá-los juntos e garantir que obtenham os mesmos padrões e configurações.

Quando usamos a ferramenta CLI para gerar uma federação, ela usa os mesmos argumentos do comandocreate-app. Ele criará uma estrutura de projeto de nível superior, e cada aplicativo independente será criado em seu subdiretório a partir daí.

7.2. Recursos

When creating a standalone application or federation, we can decide which features our app needs. Isso ajuda a garantir que o conjunto mínimo de dependências seja incluído no projeto.

Especificamos recursos usando-features argumente fornecendo uma lista separada por vírgulas de nomes de recursos.

Podemos encontrar uma lista de recursos disponíveis executando o seguinte comando:

> mn profile-info service

Provided Features:
--------------------
* annotation-api - Adds Java annotation API
* config-consul - Adds support for Distributed Configuration with Consul
* discovery-consul - Adds support for Service Discovery with Consul
* discovery-eureka - Adds support for Service Discovery with Eureka
* groovy - Creates a Groovy application
[...] More features available

7.3. Projetos Existentes

We can also use the CLI tool to modify existing projects. nos permitindo criar beans, clientes, controladores e mais. Quando executamos o comandomn de dentro de um projeto existente, teremos um novo conjunto de comandos disponíveis:

> mn help
| Command Name         Command Description
-----------------------------------------------
create-bean            Creates a singleton bean
create-client          Creates a client interface
create-controller      Creates a controller and associated test
create-job             Creates a job with scheduled method

8. Conclusão

Nesta breve introdução ao Micronaut, vimos como é fácil construir servidores e clientes HTTP bloqueadores e não bloqueadores. Além disso, exploramos alguns recursos de sua CLI.

Mas isso é apenas uma pequena amostra dos recursos que ela oferece. Também há suporte completo para funções sem servidor, descoberta de serviço, rastreamento distribuído, monitoramento e métricas, configuração distribuída e muito mais.

E embora muitos de seus recursos sejam derivados de estruturas existentes, como Grails e Spring, ele também possui muitos recursos exclusivos que ajudam a se destacar por conta própria.

Como sempre, podemos encontrar o código de amostra acima em nossoGitHub repo.