Hybrid Deployments

Java Microservices with MicroProfile – REST APIs and Dependency Injection

Share this post:

For microservices-based Java apps, knowing how to create REST APIs is an essential skill. Eclipse MicroProfile makes it easier.

What are microservices and how do they break the existing monoliths into smaller, more easily scaled and managed application services? How does the communication between these microservice apps happen? How do they communicate with the external world? If you are a developer, I bet that I know your answer: REST APIs.

Specifically for microservices applications, Java EE provides the Java API for RESTful Web Services (JAX-RS) framework. With its annotations, HTTP-centric nature, and format independence supporting a wide variety of content types, JAX-RS helps build REST APIs on the Java EE platform. Along with the RESTful APIs, Context Dependency Injection (CDI) is equally important to manage the lifecycle of the application and to provide dependency injection. This is one of the most powerful specifications in Java EE.

In today’s installment of our Java Microservices from Spring Boot series, I will compare the implementation of two different Java microservices frameworks, Spring Boot and Eclipse MicroProfile, using our example storefront application.

Eclipse MicroProfile

Eclipse MicroProfile is optimized for developers to build microservices and cloud-native applications using enterprise Java. Using the available APIs in MicroProfile, developers can easily build small and efficient microservices with the power of traditional Java EE frameworks.

Quick recap of this Java Microservices series

In our last installment, we shared how we started our journey from Spring Boot to MicroProfile. In today’s installment, I’ll cover how we refactored our microservices with JAX-RS and CDI using Eclipse MicroProfile.

For those who may have joined late, this blog series is based on my team’s experience migrating our simple storefront application from a Spring Boot-based microservices to MicroProfile, an optimized micro services programming model for enterprise Java. This example application was originally coded using Spring Boot (source code on GitHub) and migrated to MicroProfile (source code on GitHub). Both the projects include source code and full documentation.

NB: If you would like more background on Java microservices architectures:

You can also explore the Open Liberty guides to become a MicroProfile master.

Spring Boot or MicroProfile for Java microservices apps? Choose the path of least resistance

When developers are looking to transform an existing Java EE monolith application to microservices, they have lots of options. Spring developers lean towards Spring Boot, Scala developers prefer frameworks like Play, and developers using multiple languages like Java, JavaScript, and Groovy are inclined towards Vert.x. I am a Java developer and personally prefer Java over other languages. I came across Eclipse MicroProfile and found it beneficial to build next-generation Java micro services and cloud-native applications.

The Spring Boot and MicroProfile frameworks have many of the same goals, i.e., you can do everything in MicroProfile that you can do in Spring Boot. Both of them are built on top of the same core APIs; even though there are differences in some of the APIs, the work they do is similar. Each of the frameworks have their own advantages. So, developers have freedom to choose and work with their preferred framework—Spring Boot or MicroProfile.

With that preamble out of the way, let’s dive into the details of our migration story and see how our application BlueCompute, a simple storefront app (GitHub source) was built on Spring Boot and then later migrated to Eclipse MicroProfile, the Java EE microservices framework.

Microservices app with Spring Boot: REST APIs Example

With the Spring Boot framework, REST APIs are defined using Controller classes. These classes are responsible for handling different HTTP requests. To identify those classes, the @RestController annotation is used. To specify the route, mapping is done using @RequestMapping. Annotations like @GetMapping, @PostMapping, @PutMapping, @PatchMapping, and @DeleteMapping are used to map HTTP requests. Custom HTTP status codes are specified using @ResponseStatus. Variables coming from the path are captured using @PathVariable and query string parameters are captured using @RequestParam. To consume the JSON body and deserialize it, @RequestBody is used. These are some of the annotations that are used in the example Spring Boot application. For more details, check out the BlueCompute – Spring implementation (GitHub).

Microservices app with Spring Boot: Dependency Injection Example

Inversion of Control (IC) is a software engineering principle most commonly used in object-oriented programming. It means that the control of the code is transferred to a framework or container. It can be done using various mechanisms—dependency injection is one among them. In our sample application, Inversion of Control is implemented using dependency injection.

Dependency Injection is done using autowiring. All the required dependencies are annotated with @Autowired. In our application, autowiring is done byName. This means autowiring is based on the property’s name and Spring will look for the bean based on the name of the property. If the beans are of the same type, then the names can be specified using the @Qualifier annotation.

Microservices app with MicroProfile: Example Java REST API using JAX-RS

The Java API specification for RESTful frameworks is used for developing REST APIs and exposing them via annotations.  The path for the application, which is the base URI, is identified by @ApplicationPath. The path for the individual resource is specified using @Path. Annotations like @GET, @PUT, @POST, and @DELETE are used to map HTTP requests. The annotations @Produces and @Consumes are used for MIME media types. Variables coming from the path are captured using @PathParam annotation and query string params are captured using @QueryParam. These are some of the annotations that are used in the example Java MicroProfile application. For more details, more check out the BlueCompute – MicroProfile implementation (GitHub).

Microservices app with MicroProfile: Context and Dependency Injection (CDI) Example

Contexts and Dependency Injection (CDI) is one of the most popular components in Java EE platform that simplifies application code. It provides required scopes to bind the objects to their well-defined contexts. One important feature is dependency injection. It allows developers to inject components into the application in a type-safe manner. In our example application, scopes like @ApplicationScoped, @RequestScoped are used to bind the objects appropriately; dependency injection is done by injecting the objects using @Inject annotation.

When we use the scope @ApplicationScoped, the instance is shared across all the interactions of the user within the application:

public class ItemService {

Where as when we use @RequestScoped, the instance is shared only in that particular HTTP request when the user interaction is done in CatalogService:

public class CatalogService {
       ItemService itemsRepo;

These are some of the annotations that are used in the example application. For more details, check out the BlueCompute – MicroProfile implementation (GitHub).

Our journey from Spring Boot to MicroProfile

With the Spring Boot/MicroProfile differences understood, now let’s look at how we transformed our application using the standard APIs provided by MicroProfile.

We need the Maven dependency shown below in our pom.xml to build our Java application using MicroProfile:


In the server.xml of WebSphere Liberty, we added the MicroProfile feature:


The beauty of the MicroProfile feature is its various APIs that helps us to build microservices from scratch and helps us deliver them on different runtimes. JAX-RS 2.0 and CDI 1.1 are included in the very first release of MicroProfile, as these are the basic APIs any Java EE microservice requires. It is really nice to have them all in one place and make use of them without worrying about dependencies.

Now let’s walk through the details on how the migration is done. From our example application, consider the Catalog Service in our simple storefront application. The model class Item is as follows:

public class Item {
    private long id;
    private String name;
    private String description;
    private int price;
    private String imgAlt;
    private String img;
    private int stock;
    // snip...

We began with the JAX-RS controller. As noted earlier, JAX-RS is used for providing both standard Java client and server APIs for RESTful communication by MicroProfile applications.

Below is a sample before/after snippet that gives you an idea of how the migration was done. While doing this migration, as a developer, I felt that the JAX-RS annotations were easier to understand compared to the Spring Boot annotations. I also felt that the code is more readable with JAX-RS that is specified by MicroProfile.

BEFORE: Spring Boot
AFTER: MicroProfile

The next step is to define Context Dependency Injection managed classes, with CDI handling all of the type-safe dependency injection. CDI helps us to manage the lifecycle of our objects in our application. Let’s review how we did it in our application.

If we consider the Catalog service in our example implementation, we have a class called ItemService which contains some functions, e.g., the findAll() method that helps us to get all the items in the inventory.  This class should be persistent and same instance should be used across multiple resources. This dependency injection can be done by CDI. By using CDI, the same instance of the class is injected into the application and used by it. In the Spring Boot implementation of our sample application, we used @Autowired to inject the service class. The annotation @Service shown below makes the class auto-wireable. Whereas in the MicroProfile implementation of our sample application, we used the @ApplicationScoped annotation to achieve dependency injection using the @Inject annotation.

BEFORE: Spring Boot
AFTER: MicroProfile

Hurray, that’s it! Our code is ready to run on WebSphere Liberty.

For more details on how the Catalog Service is built, have a glance here. If you are interested, you can also see how we implemented a bunch of other features that comes with MicroProfile like Config, Fault Tolerance, Health Checks, Metrics, REST Client, Open API, Open Tracing, JSON-B along with JAX-RS and CDI. To run the whole application together, please check out BlueCompute – MicroProfile implementation (GitHub).

What’s Next

In today’s world of microservices, developing RESTful APIs is an essential skill. JAX-RS is one of the most impressive REST API frameworks we have in Java EE; it helps us to build RESTful APIs of our choice using the annotations to simplify the development. Making the development of REST services easier is important! Similarly, having dependency injection is equally important in your Java EE applications. CDI allows you to manage the contexts and also helps you to inject the services in a type-safe manner. These two amazing features are enough to build a microservice—all you have to do is to use some simple annotations and add some dependency injection.

I found the Open Liberty guides to be a piece of cake—they are incredibly easy to understand and following them made my path easier. These are the ones I followed:

This blog demonstrated how we migrated our example application from Spring Boot to MicroProfile using JAX-RS and CDI. This is just the beginning; you can do lot more with Eclipse MicroProfile. For example, interesting specifications like Fault Tolerance, REST Client, Health Checks, Metrics, Open API, Open Tracing, and Config are part of Eclipse MicroProfile. We’ll return to these through this blogs series.

Our next installment will cover MicroProfile RestClient & JSON-B. Meanwhile, stay tuned and have a look at our source code available on GitHub. All the individual microservices in our simple storefront application can be run locally using Maven as well. So, it should be simple for you to import them and run them as-is locally. You can also run them on IBM Cloud and IBM Cloud Private.

Cloud Solution Architect

More Hybrid Deployments stories
May 3, 2019

Kubernetes Tutorials: 5 Ways to Get You Building Fast

Ready to start working with Kubernetes? Want to build your Kubernetes skills? The five tutorials in this post will teach you everything you need to know about how to manage your containerized apps with Kubernetes.

Continue reading

May 3, 2019

IBM Garage Method Applied to Moving to and Modernizing with IBM Cloud

The IBM Cloud Garage has expanded our expertise, patterns, and assets to guide our clients’ existing applications to “move-to-cloud” and to better manage their hybrid and multicloud environments by leveraging a variety of IBM Cloud capabilities.

Continue reading

May 2, 2019

Video – What is a DDoS Attack?

Ryan Sumner, Chief Networking Architect, gives an overview of DDoS attacks and just how the attacker's botnet can affect the target application and its users.

Continue reading