Emily Jiang is a senior technical staff member at IBM and advocate for MicroProfile and CDI. She presented on choosing between MicroProfile and Spring for building cloud-native microservices. Some key points from the document include:
- MicroProfile is an open specification for enterprise Java microservices that includes specifications for REST services, configuration, fault tolerance, security and more. It has seen 9 platform releases since 2016.
- Spring is a popular framework for building microservices that includes features like REST, dependency injection, API documentation, reactive programming and more.
- Both MicroProfile and Spring provide options for building cloud-native microservices in Java, with MicroProfile being more standards-based while Spring is a
1. Emily Jiang, Java Champion
Senior Technical Staff Member, IBM
Liberty Microservice Architect, Advocate
Senior Lead for MicroProfile and CDI
@emilyfhjiang
Creating a cloud-native microservice
– which programming mode should I use?
7. Open specifications
Wide vendor support
REST services
OpenAPI support
Security
Fault Tolerance
Configuration
Metrics
Health
Open Tracing
https://wiki.eclipse.org/MicroProfile/Implementation
Implementations
8. Spring MicroProfile
Getting started
Starter https://start.spring.io/ https://start.microprofile.io/
REST
REST Service Spring MVC JAX-RS
Dependency Injection Spring IoC & DI CDI
API Documentation Spring REST Docs MP Open API
REST Client Spring MVC
Feign
MP REST Client
JSON Binding/Processing Bring Your Own Llibrary
Jackson, JSON-B
JSON-B
JSON-P
Reactive
Reactive Spring Reactor
Use Kafka APIs to connect
with Kafka
MicroProfile Reactive Streams
Operator, RxJava
MicroProfile Reactive
Messaging
Handling 100s of Services
Configuration Spring Boot Config
Spring Cloud Config
MP Config
Fault Tolerance Netflix Hystrix MP Fault Tolerance
Security Spring Security
Spring Cloud Security
EE Security
MP JWT Propagation
Operation Focus
Health Checks Spring Boot Actuator MP Health Check
Metrics Spring Boot Actuator MP Metrics
Distributed Tracing Spring Cloud Sleuth MP Open Tracing
Capabilities
12. REST Services
@ApplicationPath("/rest")
public class CatalogApplication
extends Application {
}
@Path("/items")
@Produces(MediaType.APPLICATION_J
SON)
public class CatalogService {..}
@GET
public List<Item> getInventory()
{…}
@GET
@Path("{id}")
public Response
getById(@PathParam("id") long id)
{…}
@SpringBootApplication
public class Application {
public static void main(String[] args)
{
SpringApplication.run(Application.class,
args);}
}
@RestController
public class CatalogController {..}
@RequestMapping(value = "/items", method
= RequestMethod.GET)
@ResponseBody
List<Item> getInventory() {..}
@RequestMapping(value = "/items/{id}",
method = RequestMethod.GET)
ResponseEntity<?> getById(@PathVariable
long id) {…}
Spring MicroProfile
13. JAX-RS in MicroProfile
B
@ApplicationPath("System")
public class SystemApplication extends
Application {}
@Path("properties")
public class PropertiesResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public JsonObject getProperties() {…}
}
15. Dependency Injection
@ApplicationPath("/rest")
public class JaxrsApplication extends
Application {
@Inject
private InventoryRefreshTask
refreshTask;
@ApplicationScoped
public class InventoryRefreshTask {
…
}
@SpringBootApplication
public class Application {
@Autowired
private InventoryRefreshTask
refreshTask;
Spring MicroProfile B
24. JSON Binding/Processing
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
Jsonb jsonb = JsonbBuilder.create();
String result = jsonb.toJson(artists);
import
com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
final ObjectMapper objMapper = new ObjectMapper();
jsonString = objMapper.writeValueAsString(item);
// or
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
Jsonb jsonb = JsonbBuilder.create();
String result = jsonb.toJson(artists);
MicroProfile
Spring
25. JSON-B & JSON-P in MicroProfile
A B
...
@GET
@Produces(MediaType.APPLICATION_JSON)
public InventoryList listContents() {
return manager.list();
}
public class InventoryList {
private List<SystemData> systems;
public InventoryList(List<SystemData> systems) {
this.systems = systems;
}
public List<SystemData> getSystems() {
return systems;
}
public int getTotal() {
return systems.size();
}
}
26. Reactive
MicroProfile Reactive Stream Operators
to work with Reactive Streams
Can also use RxJava
MicroProfile Reactive Messaging
Spring
MicroProfile
Use Spring Reactor
Directly use Kafka APIs or Spring boot
annotations to interact with Kafka
streams
@KafkaListener(topics = "users", groupId = "group_id")
public void consume(String message){
…
}
@Autowired
private KafkaTemplate<String,String> kafkaTemplate;
public void sendMessage(String message){
logger.info(String.format("$$ -> Producing message
--> %s",message));
this.kafkaTemplate.send(TOPIC,message);
}
35. MicroProfile JWT
A B
@GET
@RolesAllowed({ "admin", "user" })
@Path("{hostname}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPropertiesForHost(@PathParam("hostname") String hostname,
@Context HttpHeaders httpHeaders) {…}
36. Handling 100s of collaborating services
requires a strong operations focus
37. Health Checks
MP Health
Custom health implementation
/health/ready
@Readiness
public class HealthEndpoint
implements ReadinessHealthCheck {
@Override
public HealthCheckResponse
call() {…}
}
/health/live
@Liveness
public class LivenessHealthEndpoint
implements HealthCheck {
@Override
public HealthCheckResponse
call() {…}
}
SpringBoot Actuator
/health – provides us basic health info.
Custom health implementation
@Component
public class HealthCheck implements
HealthIndicator {
@Override
public Health health() {
int errorCode = check(); //
perform some specific health check
if (errorCode != 0) {
return Health.down()
.withDetail("Error
Code", errorCode).build();
}
return Health.up().build();
}
public int check() {
// Our logic to check health
return 0;
}
}
Spring MicroProfile
38. Metrics
MP Metrics - /metrics endpoint
import
org.eclipse.microprofile.metrics.annotation.Counte
d;
import
org.eclipse.microprofile.metrics.annotation.Metere
d;
import
org.eclipse.microprofile.metrics.annotation.Timed;
@Timed(name = "Inventory.timer", absolute = true,
displayName="Inventory Timer", description =
"Time taken by the Inventory", reusable=true)
@Counted(name="Inventory", displayName="Inventory
Call count", description="Number of times the
Inventory call happened.", monotonic=true,
reusable=true)
@Metered(name="InventoryMeter",
displayName="Inventory Call Frequency",
description="Rate of the calls made to Inventory",
reusable=true)
// Get all rows from database
public List<Item> findAll(){ }
Spring Actuator - /metrics endpoint
Custom Metrics implementation
@Service
public class LoginServiceImpl {
private final CounterService
counterService;
public List<Item> findAll (CounterService
counterService) {
this.counterService = counterService;
if(list.size()>1)
counterService.increment("counter.list.valid
");
else
counterService.increment("counter.list.invalid
");
……………..
………………
……………….
}
Spring MicroProfile
39. Distributed Tracing
MP OpenTracing
Configuring this features allows us to generate traces for the application
Custom Trace Implementation
import org.eclipse.microprofile.opentracing.Traced;
import io.opentracing.ActiveSpan;
import io.opentracing.Tracer;
@Traced(value = true, operationName ="getCatalog.list")
public List<Item> getInventory() {
try (ActiveSpan childSpan = tracer.buildSpan("Grabbing
messages from Messaging System").startActive()) { }
}
Spring Cloud Sleuth
If the Spring cloud sleuth is configured on the class path, the trace information
will get generated automatically.
Spring
MicroProfile
40. Our Perspectives
• Developers should be free to choose
what they prefer
• Enterprise should provide developers
with platforms that enable innovation and
flexibility and are enterprise and
production ready
• Liberty supports both MicroProfile/EE
and Spring
• Fast, small, reliable runtime
• Optimized for containers and cloud
• True liberty for microservice developers
and administrators
• Spring is popular
• MicroProfile and Jakarta EE are evolving
rapidly (and gaining momentum) as
community-driven and standards-based
efforts for developing microservices and
cloud-native applications in enterprise
Java
• Both Spring and MicroProfile provide
facilities for developers to build next-
generation applications for cloud
• Share similarities
• There are differences too (and
sometimes, significant)
• Lightweight runtimes for Java/Jakarta EE
are readily available nowadays
41. Spring Impl MicroProfile Impl
APIs Open Source
Driven by Pivotal
Spring way of things
Open Source
Driven by Community
Open standards
Behaviors in accordance
specifications
Line
s of
Cod
e
More code
Do what you want/need with
code (and configuration)
Less code
Customize server configuration
Libr
arie
s/De
pen
den
cies
Find, mix and match what you
like
Manage your own dependencies
Runtime provides what is needed
per specifications
Appl
icati
on
Pac
kagi
ng
Fat JARs Thin WAR
Note: Liberty has optimized
support for Spring Boot apps in
containers