Micronaut: Changing the Micro Future

Information about Micronaut: Changing the Micro Future

Published on October 17, 2020

Author: zak89s

Source: slideshare.net

Content

1. © 2020 Object Computing, Inc. (OCI) All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing, Inc. (OCI) Micronaut: Changing The Micro Future micronaut.io

2. About Me • Senior Software Engineer • Web & JVM developer for 10+ years • Husband and father • OSS contributor • 2GM Team Member at OCI Zachary Klein

3. Agenda ❖ A Brief History ❖ Why Micronaut? ❖ What is Micronaut? ❖ An Introduction to… ‣ Creating an app ‣ Controllers ‣ Testing ‣ HTTP Clients ‣ Dependency Injection ‣ Application configuration ‣ Annotations ‣ Micronaut Data ‣ Micronaut resources & Community ❖ Q & A

4. Copyright © 2018 by Object Computing, Inc. (OCI). All rights reserved.

5. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Rise of the Microservices ❖ Limitations of JVM frameworks ❖ Not designed for microservices or the cloud ❖ Provide a powerful programming model, but at high runtime cost

6. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. What [most] Frameworks Do ❖ Read Bytecode For Every Bean In The Context ❖ Synthesize Mirror Annotations ❖ Build Reflective Metadata

7. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. What’s Wrong With Reflection?

8. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. What’s Wrong With Reflection? ❖ Java’s Annotation API is limited ‣ (e.g, type erasure) ❖ Reflection has a performance cost ❖ Data caches are not shared (memory cost) ❖ Classpath scanning and dynamic class- loading are slow

9. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. A modern, JVM-based, full-stack framework for building modular, easily testable microservice and serverless applications.

10. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Goals of Micronaut ❖ Designed With Microservices In Mind ❖ Fast Startup Time - No reflection ❖ Low Memory Footprint - No reflection ❖ Small Executable Jar Files ❖ Zero Dependencies - AOT processing

11. • A framework for microservice & serverless applications • Leverages Ahead Of Time (AOT) for DI, AOP, and configuration injection • Reactive HTTP layer built on Netty • Declarative HTTP Client • “Natively Cloud Native” • Accompanied by a suite of official and community- contributed integrations and libraries Introduction to Micronaut

12. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Natively Cloud Native ❖ Service Discovery ‣ Consul, Eureka, etc… ❖ Configuration Sharing ‣ AWS, GCP, etc… ❖ Client Side Load Balancing ❖ Serverless Computing ‣ AWS Lambda ‣ Azure

13. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. What is Micronaut? • A Microservices and Serverless- focused framework • A Complete Application Framework - suitable for any type of Application • A Set of Libraries providing Dependency Injection, Aspect Oriented Programming (AOP), Configuration Management, Bean Introspection and more.. 14

14. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. What Can You Build With Micronaut? • Microservices • Serverless Applications • Message-Driven Applications with Kafka/Rabbit • CLI Applications • Android Applications • Anything with static void main(String..args) 15

15. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Some Numbers ❖ Smallest Micronaut Hello World Jar ‣ ~8mb ❖ Minimum Heap Requirements ‣ ~10mb ❖ Startup Time ‣ ~1 second ❖ No Reflection!

16. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. No Reflection ❖Annotations Are Processed At Compile Time ❖No Runtime Reflection Unless Necessary ❖More Performant At Runtime ❖Less Memory Consumption

17. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Compile-Time DI Generated Bytecode resides in the same package as your source code - your code is never altered by Micronaut

18. © 2020 Object Computing, Inc. (OCI) All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing, Inc. (OCI) Hello World!

19. © 2020 Object Computing, Inc. (OCI) All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing, Inc. (OCI) Demo

20. Creating a Micronaut App • Micronaut Launch: https:// launch.micronaut.io • SDKMan: https://sdkman.io • Homebrew/MacPorts • Binary or Source: https:// micronaut.io/download.html

21. https://launch.micronaut.io22

22. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Hello Micronaut import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; @Controller("/") public class HelloController { private MessageHelper messageHelper; public HelloController(MessageHelper messageHelper) { this.messageHelper = messageHelper; } @Get("/hello/{name}") public String hello(String name) { return messageHelper.createGreeting(name); } } No Reflection!

23. Micronaut Controllers

24. Micronaut Controllers ❖Annotated With @Controller ❖Configured As Beans ‣Subjected To DI ❖Conceptually Similar To Controllers In Other Frameworks ‣Grails ‣Spring ‣Etc…

25. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Hello Controller import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; @Controller("/") public class HelloController { @Get("/hello/{name}") public String greet(String name) { return "Hello " + name; } } $ curl http://localhost:8080/hello/World Hello World RFC-6570 URI Template https://tools.ietf.org/html/ rfc6570

26. Copyright © 2018 by Object Computing, Inc. (OCI). All rights reserved. URI Templates /books/{id} Simple match Integer id /books/1 /books/{id:2} A variable of 2 characters max Integer id /books/10 /books{/id} An optional URI variable @Nullable Integer id /books/10 or /books /book{/id:[a-zA-Z]+} An optional URI variable with regex @Nullable String id /books/foo /books{?max,offset} Optional query parameters @Nullable Integer max /books?max=10&offset=10 /books{/path:.*}{.ext} Regex path match with extension @Nullable String path /books/foo/bar.xml

27. Testing Micronaut ❖Micronaut is test-framework agnostic ❖No special tooling required for unit or integration/ functional tests ❖Simplest approach: start the ApplicationContext and test away! try (ApplicationContext context = ApplicationContext.run()) { MyBean myBean = context.getBean(MyBean.class); // test your MyBean }

28. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Test Hello Controller import io.micronaut.context.ApplicationContext import io.micronaut.http.client.HttpClient import io.micronaut.runtime.server.EmbeddedServer import spock.lang.AutoCleanup import spock.lang.Shared import spock.lang.Specification class HelloControllerSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) @Shared HttpClient client = HttpClient.create(embeddedServer.URL) void 'test greeting'() { expect: client.toBlocking().retrieve('/hello/James') == 'Hello James' } } Could Also Write a POJO Unit Test Without Running The Server

29. @MicronautTest @Property(name = "greeting.prefix", value = "Hello") class HelloControllerSpec extends Specification { @Inject HelloClient client void 'test greeting'() { expect: client.toBlocking().retrieve('/hello/James') == 'Hello James' } } ❖Testing library for Spock & JUnit 5 ❖Starts up application (inc. embedded server) and shuts it down automatically ❖Allows direct injection of beans into test classes ❖Set configuration properties with @Property Micronaut Test

30. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Test Hello Controller import io.micronaut.http.client.HttpClient import io.micronaut.http.client.annotation.Client import io.micronaut.test.annotation.MicronautTest import spock.lang.Specification import javax.inject.Inject @MicronautTest class HelloControllerSpec extends Specification { @Inject @Client('/') HttpClient client void 'test greeting'() { expect: client.toBlocking().retrieve('/hello/James') == 'Hello James' } } testCompile “io.micronaut.test:micronaut-test-spock:$mnTestVersion"

31. Reactive Controllers @Controller("/people") public class PersonController { Map<String, Person> inMemoryDatastore = new ConcurrentHashMap<>(); @Post("/saveReactive") public Single<HttpResponse<Person>> save(@Body Single<Person> person) { return person.map(p -> { inMemoryDatastore.put(p.getFirstName(), p); return HttpResponse.created(p); } ); } } ❖Support for RxJava (2 & 3), Reactor, CompleteableFuture ❖Leverages Micronaut & Netty’s reactive model

32. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut HTTP Client 33 ❖Netty-Based HTTP Client ❖Low-level API and declarative compile-time client ❖Uses @Introduction advice to simplify writing clients ❖Reactive, CompletableFuture and blocking I/O support ❖Built-in Service Discovery support ❖Support for multi-part uploads, streaming data over HTTP, etc

33. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Declarative Client Interfaces 34 import io.micronaut.http.MediaType; import io.micronaut.http.annotation.*; @Client("/hello") //or absolute URL or service ID public interface HelloClient { @Get(produces = MediaType.TEXT_PLAIN) String hello(); } src/main/java/example/micronaut/HelloClient.java

34. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Declarative Client Interfaces @MicronautTest class HelloControllerSpec extends Specification { @Inject HelloClient client void 'test greeting'() { expect: client.hello() == 'Hello World!’ } } 35

35. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Dependency Injection ❖Micronaut Contains A Full Featured Dependency Injection (DI) Container ❖Uses javax.inject.* Annotations ❖JSR-330 Compliant ‣Passes The Full TCK ❖Supports Constructor Injection As Well As Property And Field Injection ‣insert heated debate here… 36

36. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Compile-Time DI Generated Bytecode resides in the same package as your source code - your code is never altered by Micronaut 37

37. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Constructor Injection import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; @Controller("/") public class HelloController { private MessageHelper messageHelper; public HelloController(MessageHelper messageHelper) { this.messageHelper = messageHelper; } // ... } 38

38. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Property Injection import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import javax.inject.Inject; @Controller("/") public class HelloController { private MessageHelper messageHelper; @Inject public void setMessageHelper(MessageHelper messageHelper) { this.messageHelper = messageHelper; } // ... } 39

39. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Field Injection import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import javax.inject.Inject; @Controller("/") public class HelloController { @Inject // Could be private, protected, // package-protected or public private MessageHelper messageHelper; // ... } 40

40. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Dependency Injection ❖Bean Scopes @Singleton Only one instance of the bean should exist @Context Eagerly instantiated @Prototype New instance is created each time it is injected @Infrastructure Bean cannot be replaced @ThreadLocal Bean per thread via a ThreadLocal @Refreshable Bean's state to be refreshed via the `/refresh` endpoint @RequestScope New instance is created and associated with each HTTP request 41

41. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Conditional Beans ❖Bean Definitions May Be Marked With @Requires To Conditionally Load Them ❖Examples: @Requires(classes = org.hibernate.classic.Lifecycle.class) @Requires(property = “some.property") @Requires(property = “some.property”, value = "some value") @Requires(beans = javax.sql.DataSource.class) @Requires(env = "test") @Requires(notEnv = "test") @Requires(sdk = Requires.Sdk.JAVA, version = “1.8") 42

42. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Replaceable Beans ❖ @Replaces May Be Used In Conjunction With @Requires To Optionally Replace Beans @Singleton @Requires(beans = DataSource.class) public class JdbcBookService implements BookService { // Real BookService Impl... } @Singleton @Requires(env = Environment.TEST) @Replaces(JdbcBookService.class) public class MockBookService implements BookService { // Mock BookService Impl... } 43

43. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. PostConstruct @Refreshable public static class WeatherService { private String forecast; @PostConstruct public void init() { forecast = "Scattered Clouds " + new SimpleDateFormat("dd/MMM/yy HH:mm:ss.SSS”) .format(new Date()); } public String latestForecast() { return forecast; } } 44

44. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. PreDestroy import javax.annotation.PreDestroy; import javax.inject.Singleton; import java.util.concurrent.atomic.AtomicBoolean; @Singleton public class PreDestroyBean implements AutoCloseable { AtomicBoolean stopped = new AtomicBoolean(false); @PreDestroy @Override public void close() throws Exception { stopped.compareAndSet(false, true); } } 45

45. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Application Configuration 46

46. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Config Files ❖Micronaut Supports Multiple Formats ❖Defined In src/main/resources/ ‣application.properties ‣application.yml ‣application.groovy ‣application.json ❖Environment specific configuration with -suffix: ‣application-test.yml ‣application-gcp.yml https://docs.micronaut.io/latest/api/io/micronaut/context/env/Environment.html 47

47. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Alternate Config Sources ❖SPRING_APPLICATION_JSON ❖MICRONAUT_APPLICATION_JSON ❖System Properties ❖OS Environment Variables ❖Cloud Configuration ❖application-[env].[extension] ‣env = runtime environment 48

48. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Injecting Config Values ❖Config Values May Be Injected Into Property References Using @Value(…) import io.micronaut.context.annotation.Value; @Controller(“/") public class SomeController { @Value("${some.config.value}") protected String someProperty; // ... } 49

49. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Default Config Values ❖ @Value(…) Supports A Default Value import io.micronaut.context.annotation.Value; @Controller("/") public class SomeController { @Value("${some.config.value:99}") protected String someProperty; // ... } 50

50. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Property Placeholders ❖ ${value:default} Syntax can be used in all Micronaut annotations for config injection ❖Great for API versioning (but check out @Version first!) import io.micronaut.context.annotation.Value; @Controller(“${some.controller.path:/some}”) public class SomeController { @Value("${some.config.value:99}") protected String someProperty; // ... } 51

51. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Retryable ❖Indicates that the method call should be re- attempted for a configurable number of times, before throwing an exception 52 @Retryable( attempts = “5", delay = “2s" ) public Book findBook(String title) { //... @Retryable(attempts = "${book.retry.attempts:3}", delay = "${book.retry.delay:1s}" )

52. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Circuit Breaker ❖Variation of @Retryable which (after a set number of failures) will immediately re-throw the exception without waiting for the method to fail 53 @CircuitBreaker( attempts = “5", delay = “2s” reset = “30s” ) public Book findBook(String title) { //...

53. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Cacheable ❖Annotate classes and methods to specify caching behavior 54 @Singleton @CacheConfig("headlines") public class NewsService { @Cacheable public List<String> headlines(Month month) { //This method is cacheable } @CachePut(parameters = {"month"}) public List<String> addHeadline(Month month, String headline) { //Return value is cached with name headlines for the supplied month. } @CacheInvalidate(parameters = {"month"}) public void removeHeadline(Month month, String headline) { //invalidates the cache headlines for the supplied month. } }

54. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Scheduled ❖Annotation for scheduling background tasks (can also be done programmatically via TaskScheduler) 55 @Scheduled(fixedDelay = "5m") void fiveMinutesAfterLastExecution() { System.out.println("Executing fiveMinutesAfterLastExecution()") } @Scheduled(cron = "0 15 10 ? * MON" ) void everyMondayAtTenFifteenAm() { System.out.println("Executing everyMondayAtTenFifteenAm()") } @Scheduled(initialDelay = "1m" ) void onceOneMinuteAfterStartup() { System.out.println("Executing onceOneMinuteAfterStartup()") }

55. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data ❖Database Access Toolkit ❖Developed By Micronaut Team ❖Key Distinguishing Factors: ‣Queries Computed At Compile Time ‣No Runtime Reflection ‣No Query Translation ‣GraalVM support! ❖GA release in February 2020 56

56. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data JDBC Dependencies // ... dependencies { annotationProcessor “io.micronaut.data:micronaut-data-processor" implementation "io.micronaut.data:micronaut-data-jdbc" implementation “io.micronaut.sql:micronaut-jdbc-hikari" runtimeOnly “com.h2database:h2" // ... } 57 JDBC

57. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data Entity // src/main/java/demo/Car.groovy package demo; import io.micronaut.data.annotation.MappedEntity; import io.micronaut.data.annotation.GeneratedValue; import io.micronaut.data.annotation.Id; @MappedEntity public class Car { @Id @GeneratedValue private Long id; private String make; private String model; // … } 58

58. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data Repository package demo; import io.micronaut.data.jdbc.annotation.JdbcRepository; import io.micronaut.data.model.query.builder.sql.Dialect; import io.micronaut.data.repository.CrudRepository; @JdbcRepository(dialect = Dialect.MYSQL) public interface CarRepository extends CrudRepository<Car, Long> {} 59

59. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data Repository package demo; import io.micronaut.data.jdbc.annotation.JdbcRepository; import io.micronaut.data.model.query.builder.sql.Dialect; import io.micronaut.data.repository.CrudRepository; @JdbcRepository(dialect = Dialect.MYSQL) public interface CarRepository extends CrudRepository<Car, Long> { void update(@Id long id, String make, String model); Car save(String make, String model); } 60

60. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data Repository package demo; import io.micronaut.data.jdbc.annotation.JdbcRepository; import io.micronaut.data.model.query.builder.sql.Dialect; import io.micronaut.data.repository.CrudRepository; @JdbcRepository(dialect = Dialect.MYSQL) public interface CarRepository extends CrudRepository<Car, Long> { CarDTO findById(Long id) // Will only query for fields in the DTO } 61 <logger name="io.micronaut.data.query" level="trace" />

61. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Micronaut Data Transactions 62 ❖Programmatic: Micronaut or Spring TransactionManager API supported ❖Declarative: @Transactional on the method

62. Micronaut Resources ❖https://micronaut.io/launch ❖docs.micronaut.io ❖guides.micronaut.io ❖micronaut.io/blog/index.html ❖micronaut.io/faq.html ❖github.com/micronaut-projects/micronaut-core ❖https://micronaut.io/foundation

63. Micronaut Community Resources ❖gitter.im/micronautfw ❖https://github.com/jhipster/jhipster-sample- app-micronaut ❖https://developer.okta.com/blog/ 2020/08/17/micronaut-jhipster-heroku ❖https://github.com/JonasHavers/awesome- micronaut

64. https://launch.micronaut.io65

65. Copyright © 2020 by Object Computing, Inc. (OCI). All rights reserved. Questions? Zachary Klein Software Engineer at Object Computing [email protected] Twitter: @ZacharyAKlein Gifthub: Zachary Klein

66. © 2020 Object Computing, Inc. (OCI) All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing, Inc. (OCI) OCI Contact Information Zachary Klein Software Engineer at Object Computing [email protected] Twitter: @ZacharyAKlein Gifthub: Zachary Klein Jen Wiese Micronaut and Grails Product Evangelist [email protected] (314) 579-0066 micronaut.io

Related presentations


Other presentations created by zak89s

Shields Up! Securing React Apps
10. 12. 2017
0 views

Shields Up! Securing React Apps

Groovy for Java Devs
08. 03. 2019
0 views

Groovy for Java Devs