Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Microservices Deployment Cookbook
Microservices Deployment Cookbook

Microservices Deployment Cookbook: Deploy and manage scalable microservices

eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Microservices Deployment Cookbook

Chapter 1. Building Microservices with Java

In this chapter, we will cover the following recipes:

  • Creating a project template using STS and Maven
  • Writing microservices with Spring Boot
  • Writing REST APIs with Spring MVC
  • Writing microservices with WildFly Swarm
  • Writing microservices with Dropwizard
  • Writing REST APIs with SparkJava

Microservices have gained a lot of traction recently. A microservice-based architecture is one way of designing your software. In such an architecture, applications are broken down into smaller services so that they can be deployed and managed separately. This takes away a lot of pain points that occur in traditional monolithic applications. With that being said, microservices can be built using any programming language. In fact, there are many libraries and frameworks that help programmers build microservices using Java, Scala, C#, JavaScript, Python, Ruby, and so on. In this book, we will focus more on building and deploying microservices with Java.

Introduction

In a traditional microservice-based design, monolithic applications will be broken down into smaller services that can talk to other services either in a synchronous or asynchronous model, based on the need and use case. The first question that anyone would have when breaking down monolithic applications is "what are the potential services that my application can be broken down into?" There is no rule of thumb or straight-forward answer to this. But usually, one looks for independent functionalities. Each and every functionality can be considered to be built as its own service.

To illustrate this, let's take a look at an example application and see how it could be broken down into smaller, manageable and deployable microservices. The sample application we will be looking at is a biker tracking application. This application will have the following functionalities:

  • Web interface to monitor the user's progress on a map
  • REST API to consume the user's geolocation data constantly
  • Analytics code to perform calculations for biking route suggestions, weather predictions, biking gear suggestions, calories burnt, water intake, and so on

Let's take a look at how this application might have been designed as a monolithic application:

Introduction

As you can see, the whole application is bundled as one artifact and therefore promotes a single point of failure (SPOF). If for some reason the analytics code crashes your JVM, we will lose the web interface, REST APIs, and analytics as a whole. Now, let's take a look at how this might be broken down into manageable microservices:

Introduction

In this architecture diagram, you can see that each and every functionality is deployed as its own microservice. The service implementations have been broken down into a Notification Service, which will take care of sending notifications to the users, and the Geo Location Tracker Service, which keeps track of the geolocation (latitude and longitude) information of all the users. The Analytics code has been broken down into its own microservices. So if one type of analytics microservice goes down, the other microservices will keep functioning properly. You might have noticed that the REST APIs are missing. They are actually not missing, but integrated into their respective microservices.

Now let's not waste any more time and jump directly into building one part of this application. To be able to illustrate the extensive concepts that this book offers, I have chosen the geolocation tracker service as our example microservice. This service will be responsible for collecting the geolocation of all users of this application and then storing them in a data store.

Creating a project template using STS and Maven

Creating a project for your microservice is no different than creating a simple Java project. We will use Maven as our build framework as it is considered to be one of the most popular build frameworks. If you are comfortable using other frameworks, such as Gradle, SBT, or Ivy, feel free to use them. But keep in mind that the recipes throughout this book will use Maven extensively. Unless you are an expert in your preferred framework, I strongly recommend using Maven.

Getting ready

In order to create your microservice project, you will need the following software. Follow the instructions on their respective websites to install them:

  • JDK 1.8+
  • Maven 3.3.9+
  • Spring Tool Suite (STS) 3.8.0+

Make sure both Java and Maven are in your PATH variable so that you can use the java and mvn commands on every terminal shell without having to set PATH each time. Spring Tool Suite is a sophisticated version of Eclipse that has lot of Spring plugins and extensions. If you are familiar with other IDEs, feel free to use them. But for familiarity, this book will use STS for all recipes.

How to do it...

After you have installed the above-mentioned software, open Spring Tool Suite. The first time you open it, you will be requested to choose a workspace. Go ahead and enter your workspace location. In this recipe, we will learn how to create a template Maven project using STS and Maven. STS comes with Maven Integration out of the box. So we don't have to configure it any further. After your STS IDE has completed startup, follow the below instructions to create a new Maven project:

  1. In your STS window, right-click anywhere on the Package Explorer, select New, and then select Maven Project, as shown in the following screenshot:

    How to do it...

  2. This will open a popup that will let you chose the type of Maven project you would like to create. We will skip the archetype selection by checking the box that says Create a simple project (skip archetype selection) and then hit Next:

    How to do it...

  3. In the next window, enter the following details to create your project:
    • Group Id: com.packt.microservices
    • Artifact Id: geolocation
    • Name: geolocation
  4. After you have entered the details, hit Finish:

    How to do it...

  5. This will create a simple Maven JAR module with all the required directories in place. Depending on your IDE settings, STS configures your new project with the default Java version. If you have not set any defaults, it will configure your project with Java 1.5. You can verify this by checking your project structure in STS. The following screenshot shows that STS uses Java 1.5 for your project:

    How to do it...

  6. We will use Java 8's lambda expressions in other chapters. So let's change the Java version from 1.5 to 1.8. In order to change the Java version, we will configure the maven-compiler-plugin in the pom.xmlfile. Add the following section of code to your pom.xml file's project section:
            <build> 
              <plugins> 
               <plugin> 
                  <groupId>org.apache.maven.plugins</groupId> 
                  <artifactId>maven-compiler-plugin</artifactId> 
                <version>3.5.1</version> 
                <configuration> 
                  <source>1.8</source> 
                  <target>1.8</target> 
                </configuration> 
               </plugin> 
             </plugins> 
            </build> 
    
  7. Save your pom.xml file, right-click on your project, choose Maven, and then hit Update Project... or use the keyboard shortcut Alt + F5. This will automatically change your project's Java version to 1.8.
  8. Our microservice project is now ready to play with.

There's more...

If you are more comfortable using the command line to create Maven projects, issue the following command in your terminal to create the new project:

mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.packt.microservices -DartifactId=geolocation \ 
-Dname=geolocation

After Maven creates the project, you should be able to import your project into your IDE. As this is something out of the scope of this book, we will not be looking at how to import an existing Maven project into your IDE.

Writing microservices with Spring Boot

Now that our project is ready, let's look at how to write our microservice. There are several Java-based frameworks that let you create microservices. One of the most popular frameworks from the Spring ecosystem is the Spring Boot framework. In this recipe, we will look at how to create a simple microservice application using Spring Boot.

Getting ready

Any application requires an entry point to start the application. For Java-based applications, you can write a class that has the main method and run that class as a Java application. Similarly, Spring Boot requires a simple Java class with the main method to run it as a Spring Boot application (microservice). Before you start writing your Spring Boot microservice, you will also require some Maven dependencies in your pom.xml file.

How to do it...

  1. Create a Java class called com.packt.microservices.geolocation.GeoLocationApplication.java and give it an empty main method:
            package com.packt.microservices.geolocation;  
              public class GeoLocationApplication {  
                public static void main(String[] args) { 
                // left empty intentionally 
               } 
              } 
    
  2. Now that we have our basic template project, let's make our project a child project of Spring Boot's spring-boot-starter-parent pom module. This module has a lot of prerequisite configurations in its pom.xml file, thereby reducing the amount of boilerplate code in our pom.xml file. At the time of writing this, 1.3.6.RELEASE was the most recent version:
            <parent> 
              <groupId>org.springframework.boot</groupId> 
              <artifactId>spring-boot-starter-parent</artifactId> 
              <version>1.3.6.RELEASE</version> 
            </parent> 
    
  3. After this step, you might want to run a Maven update on your project as you have added a new parent module. If you see any warnings about the version of the maven-compiler  plugin, you can either ignore it or just remove the <version>3.5.1</version> element. If you remove the version element, please perform a Maven update afterward.
  4. Spring Boot has the ability to enable or disable Spring modules such as Spring MVC, Spring Data, and Spring Caching. In our use case, we will be creating some REST APIs to consume the geolocation information of the users. So we will need Spring MVC. Add the following dependencies to your pom.xml file:
            <dependencies> 
              <dependency> 
                <groupId>org.springframework.boot</groupId> 
                <artifactId>spring-boot-starter-web</artifactId> 
              </dependency> 
            </dependencies> 
    
  5. We also need to expose the APIs using web servers such as Tomcat, Jetty, or Undertow. Spring Boot has an in-memory Tomcat server that starts up as soon as you start your Spring Boot application. So we already have an in-memory Tomcat server that we could utilize.
  6. Now let's modify the GeoLocationApplication.java class to make it a Spring Boot application:
            package com.packt.microservices.geolocation; 
            import org.springframework.boot.SpringApplication; 
            import org.springframework.boot.autoconfigure
             .SpringBootApplication; 
              @SpringBootApplication 
              public class GeoLocationApplication { 
                public static void main(String[] args) {
                SpringApplication.run(GeoLocationApplication.class, args); 
               } 
              } 
    

As you can see, we have added an annotation, @SpringBootApplication, to our class. The @SpringBootApplication annotation reduces the number of lines of code written by adding the following three annotations implicitly:

  • @Configuration
  • @ComponentScan
  • @EnableAutoConfiguration

If you are familiar with Spring, you will already know what the first two annotations do. @EnableAutoConfiguration is the only annotation that is part of Spring Boot. The AutoConfiguration package has an intelligent mechanism that guesses the configuration of your application and automatically configures the beans that you will likely need in your code.

You can also see that we have added one more line to the main method, which actually tells Spring Boot the class that will be used to start this application. In our case, it is GeoLocationApplication.class. If you would like to add more initialization logic to your application, such as setting up the database or setting up your cache, feel free to add it here.

  1. Now that our Spring Boot application is all set to run, let's see how to run our microservice. Right-click on GeoLocationApplication.java from Package Explorer, select Run As, and then select Spring Boot App. You can also choose Java Application instead of Spring Boot App. Both the options ultimately do the same thing. You should see something like this on your STS console:

    How to do it...

  2. If you look closely at the console logs, you will notice that Tomcat is being started on port number 8080. In order to make sure our Tomcat server is listening, let's run a simple curl command. cURL is a command-line utility available on most Unix and Mac systems. For Windows, use tools such as Cygwin or even Postman. Postman is a Google Chrome extension that gives you the ability to send and receive HTTP requests. For simplicity, we will use cURL. Execute the following command on your terminal:
          curl http://localhost:8080
    
  3. This should give us an output like this:
          {"timestamp":1467420963000,"status":404,"error":"Not
          Found","message":"No message available","path":"/"}
    
    

This error message is being produced by Spring. This verifies that our Spring Boot microservice is ready to start building on with more features. There are more configurations that are needed for Spring Boot, which we will perform later in this chapter along with Spring MVC.

Writing REST APIs with Spring MVC

There are two types of communication models. One of them is synchronous, where the client waits for the server to respond to its request. The other is asynchronous, where the client fires a request and forgets. Though Servlet 3.0 and above let you create asynchronous servlets, in our recipes, we will focus on traditional servlet-based HTTP APIs for simplicity. We will also be looking at asynchronous communication in later chapters.

Getting ready

When it comes to building REST APIs, there are several frameworks to choose from. As we already set up the Spring ecosystem in our previous recipe, it would make more sense and be much easier to use Spring MVC to expose REST APIs.

How to do it...

The true advantage of Spring Boot is that you do not have to add any new dependencies to enable web support for your application. Spring Boot's parent pom file (spring-boot-starter-parent) takes care of that for you. Now let's take a look at how to write our first API. If you are familiar with Spring MVC, this should be really straight-forward for you:

  1. Create a Controller class called com.packt.microservices.geolocation.GeoLocationController.java, which will be responsible for basic CRUD operations for the geolocation of all users:
            package com.packt.microservices.geolocation; 
     
            import org.springframework.web.bind.annotation.RequestMapping; 
            import org.springframework.web.bind.annotation.RestController; 
     
            @RestController 
            @RequestMapping("/geolocation") 
            public class GeoLocationController { 
     
            } 
    

    There are two things to note here. The @RestController annotation indicates that we are going to use this controller to expose our REST APIs. It implicitly adds the @ResponseBody annotation to all controller methods as that is something you would want to do when exposing your REST APIs using Spring MVC. The @RequestMapping annotation specifies where your HTTP resource is located. We are setting @RequestMapping on the controller level to apply it to all controller methods.

    Note

    Using @RequestMapping on the Controller class level to define a root resource path is considered to be one of the best practices. Instead of having to create API paths such as /getGeolocation or /createGeolocation, it is always a better practice to use the same path, /geolocation, with the GET method to get geolocation data and the POST method to create geolocation data.

  2. Before we jump into creating our APIs, we will need some classes for the domain object and service. Let's start with creating our domain object. Assume that our GeoLocation consists latitude and longitude. We will be defining both latitude and longitude as double to provide better precision. Now we will have to say which user's geolocation it is. So we might want to add a userId. We also need to say at what time the user was at the geolocation. So we might want to add a timestamp in EPOCH time format. The timestamp will be of type long. This is how your plain old java object (POJO) class will look:
            package com.packt.microservices.geolocation; 
    
            import java.io.Serializable; 
            import java.util.UUID; 
     
              public class GeoLocation implements Serializable { 
     
                private static final long serialVersionUID = 1L; 
       
               private double latitude; 
               private double longitude; 
               private UUID userId; 
               private long timestamp; 
       
              public double getLatitude() { 
                return latitude; 
              } 
       
              public void setLatitude(double latitude) { 
                this.latitude = latitude; 
              } 
       
              public double getLongitude() { 
               return longitude; 
              } 
       
              public void setLongitude(double longitude) { 
                this.longitude = longitude; 
              } 
       
              public UUID getUserId() { 
               return userId; 
              } 
       
              public void setUserId(UUID userId) { 
               this.userId = userId; 
              } 
       
             public long getTimestamp() { 
              return timestamp; 
             } 
       
             public void setTimestamp(long timestamp) { 
              this.timestamp = timestamp; 
             } 
            } 
    

    As you can see, we have used the java.util.UUID class to represent the userId, assuming that this UUID uniquely identifies a user. We will not be creating the user POJO as it is out of scope for this recipe.

    In an ideal scenario, one would be using a NoSQL or relational database to store the geolocations. In this case, NoSQL sounds more suitable due to several reasons, including the fact that our data is time series data, in JSON format, unstructured but will change over time and we will have a humongous amount of data.

  3. For simplicity purposes, we will be storing our geolocations in an in-memory java.util.List<GeoLocation> collection. Let's create our repository that holds all our geolocation objects, com.packt.microservices.geolocation.GeoLocationRepository.java:
            package com.packt.microservices.geolocation; 
     
            import java.util.ArrayList; 
            import java.util.Collections; 
            import java.util.List; 
     
            import org.springframework.stereotype.Repository; 
     
            @Repository 
            public class GeoLocationRepository { 
     
              private List<GeoLocation> geolocations = new
              ArrayList<GeoLocation>(); 
       
                public void addGeoLocation(GeoLocation geolocation) { 
                  geolocations.add(geolocation); 
                } 
       
               public List<GeoLocation> getGeoLocations() { 
                  return Collections.unmodifiableList(geolocations); 
               } 
             } 
    
  4. Now let's take a look at how your Service interface will look:
            package com.packt.microservices.geolocation; 
     
            import java.util.List; 
     
            public interface GeoLocationService { 
     
              public GeoLocation create(GeoLocation geolocation); 
              public List<GeoLocation> findAll(); 
            }  
    
  5. Both our repository and service have a very simple interface. Ideally in real-time applications, you might want to add more complicated methods that not only perform CRUD operations but also sort, filter, select only specific fields, and so on. Now let's take a look at our com.packt.microservices.geolocation.GeoLocationServiceImpl.java class:
            package com.packt.microservices.geolocation; 
     
            import java.util.List; 
     
            import org.springframework.beans.factory.annotation.Autowired; 
     
            import org.springframework.stereotype.Service; 
     
            @Service 
            public class GeoLocationServiceImpl implements
            GeoLocationService { 
       
              @Autowired 
              private GeoLocationRepository repository; 
     
              @Override 
              public GeoLocation create(GeoLocation geolocation) { 
               repository.addGeoLocation(geolocation); 
               return geolocation; 
              } 
     
              @Override 
              public List<GeoLocation> findAll() { 
                return repository.getGeoLocations(); 
              } 
            }

    Note

    It is always strongly recommended that you write unit test cases for any new code. But as that is a little out of scope for this book, we will not be writing unit test cases for any of the previous code. To learn more about unit testing Spring Boot applications, please take a look at Spring Boot's documentation at https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html.

  6. Now that our domain and service classes are all set to go, let's modify our Controller class to save and find geolocations. Add the following snippet into your Controller class body:
            @Autowired
            private GeoLocationService service;
    
            @RequestMapping(method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
            public GeoLocation create(@RequestBody GeoLocation geolocation) {
              return service.create(geolocation);
            }
      
            @RequestMapping(method = RequestMethod.GET, produces = "application/json")
            public List<GeoLocation> findAll() {
              return service.findAll();
            } 
    

In this implementation, there are a few things to notice. The @RequestMapping annotation does not have a path defined as it is already derived from the class-level annotation. For both the create and findAll methods, we are using the same path but different HTTP methods as per best practice. Since we are dealing only with JSON here, we have set the produces and consumes values to application/json. The return types of the create and findAll methods are GeoLocation and List<GeoLocation> respectively. Spring MVC internally uses Jackson to convert them to their equivalent JSON strings.

That's it! We are now ready to test our application:

  1. Let's try to create two geolocations using the POST API and later try to retrieve them using the GET method. Execute the following cURL commands in your terminal one by one:
          curl -H "Content-Type: application/json" -X POST -d'{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:8080/geolocation
    
  2. This should give you an output similar to the following (pretty-printed for readability):
            { 
             "latitude": 41.803488, 
             "longitude": -88.14404, 
             "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", 
             "timestamp": 1468203975 
            } 
     
     
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:8080/geolocation
    
  3. This should give you an output similar to the following (pretty-printed for readability):
    {
              "latitude": 9.568012,
              "longitude": 77.962444,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
  4. To verify whether your entities were stored correctly, execute the following cURL command:
          curl http://localhost:8080/geolocation
    
  5. This should give you an output similar to the following (pretty-printed for readability):
            [ 
            { 
              "latitude": 41.803488, 
              "longitude": -88.14404, 
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", 
              "timestamp": 1468203975 
            }, 
            { 
              "latitude": 9.568012, 
              "longitude": 77.962444, 
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", 
              "timestamp": 1468203975 
            } 
            ]
    

You now have a fully working version of your microservice. The remaining recipes in this chapter try to achieve the same logic with different frameworks, such as WildFly Swarm and Dropwizard. Later in this chapter, we will also look at another framework that helps you build REST APIs quickly called SparkJava (different from Apache Spark). If you will be using Spring Boot for your microservices, you can jump to the next chapter. If you are interested in any of the frameworks that were mentioned, jump to the appropriate recipe in this chapter.

Writing microservices with WildFly Swarm

WildFly Swarm is a J2EE application packaging framework from RedHat that utilizes the in-memory Undertow server to deploy microservices. In this recipe, we will create the same GeoLocation API using WildFly Swarm and JAX-RS.

To avoid confusion and dependency conflicts in our project, we will create the WildFly Swarm microservice as its own Maven project. This recipe is just here to help you get started on WildFly Swarm. When you are building your production-level application, it is your choice to either use Spring Boot, WildFly Swarm, Dropwizard, or SparkJava based on your needs.

Getting ready

Similar to how we created the Spring Boot Maven project, create a Maven WAR module with the groupId  com.packt.microservices and name/artifactId  geolocation-wildfly. Feel free to use either your IDE or the command line. Be aware that some IDEs complain about a missing web.xml file. We will see how to fix that in the next section.

How to do it...

  1. Before we set up the WildFly Swarm project, we have to fix the missing web.xml error. The error message says that Maven expects to see a web.xml file in your project as it is a WAR module, but this file is missing in your project. In order to fix this, we have to add and configure maven-war-plugin. Add the following code snippet to your pom.xml file's project section:
            <build> 
              <plugins> 
                <plugin> 
                  <groupId>org.apache.maven.plugins</groupId> 
                  <artifactId>maven-war-plugin</artifactId> 
                  <version>2.6</version> 
                  <configuration> 
                    <failOnMissingWebXml>false</failOnMissingWebXml> 
                  </configuration> 
                </plugin> 
               </plugins> 
            </build> 
    
  2. After adding the snippet, save your pom.xml file and perform a Maven update. Also, if you see that your project is using a Java version other than 1.8, follow the Creating a project template using STS and Maven recipe to change the Java version to 1.8. Again, perform a Maven update for the changes to take effect.
  3. Now, let's add the dependencies required for this project. As we know that we will be exposing our APIs, we have to add the JAX-RS library. JAX-RS is the standard JSR-compliant API for creating RESTful web services. JBoss has its own version of JAX-RS. So let's add that dependency to the pom.xml file:
            <dependencies> 
              <dependency> 
                <groupId>org.jboss.spec.javax.ws.rs</groupId> 
                  <artifactId>jboss-jaxrs-api_2.0_spec</artifactId> 
                  <version>1.0.0.Final</version> 
                  <scope>provided</scope> 
              </dependency> 
            </dependencies> 
    

    Note

    The one thing that you have to note here is the provided scope. The provided scope in general means that this JAR need not be bundled with the final artifact when it is built. Usually, the dependencies with provided scope will be available to your application either via your web server or application server. In this case, when Wildfly Swarm bundles your app and runs it on the in-memory Undertow server, your server will already have this dependency.

  4. The next step toward creating the GeoLocation API using Wildfly Swarm is creating the domain object. Use the com.packt.microservices.geolocation.GeoLocation.java file from the previous recipe.
  5. Now that we have the domain object, there are two classes that you need to create in order to write your first JAX-RS web service. The first of those is the Application class. The Application class in JAX-RS is used to define the various components that you will be using in your application. It can also hold some metadata about your application, such as your basePath (or ApplicationPath) to all resources listed in this Application class. In this case, we are going to use /geolocation as our basePath. Let's see how that looks:
           package com.packt.microservices.geolocation; 
     
           import javax.ws.rs.ApplicationPath; 
           import javax.ws.rs.core.Application; 
     
           @ApplicationPath("/geolocation") 
             public class GeoLocationApplication extends Application { 
     
              public GeoLocationApplication() {} 
             } 
    

    There are two things to note in this class; one is the Application class and the other is the @ApplicationPath annotation-both of which we've already talked about.

  6. Now let's move on to the resource class, which is responsible for exposing the APIs. If you are familiar with Spring MVC, you can compare Resource classes to Controllers. They are responsible for defining the API for any specific resource. The annotations are slightly different from that of Spring MVC. Let's create a new resource class called com.packt.microservices.geolocation.GeoLocationResource.java that exposes a simple GET API:
            package com.packt.microservices.geolocation; 
     
            import java.util.ArrayList; 
            import java.util.List; 
     
            import javax.ws.rs.GET; 
            import javax.ws.rs.Path; 
            import javax.ws.rs.Produces; 
     
            @Path("/") 
            public class GeoLocationResource { 
     
             @GET 
             @Produces("application/json") 
             public List<GeoLocation> findAll() { 
               return new ArrayList<>(); 
             } 
            } 
    

    All the three annotations, @GET, @Path, and @Produces, are pretty self explanatory.

Before we start writing the APIs and the service class, let's test the application from the command line to make sure it works as expected. With the current implementation, any GET request sent to the /geolocation URL should return an empty JSON array.

So far, we have created the RESTful APIs using JAX-RS. It's just another JAX-RS project:

  1. In order to make it a microservice using Wildfly Swarm, all you have to do is add the wildfly-swarm-plugin to the Maven pom.xml file. This plugin will be tied to the package phase of the build so that whenever the package goal is triggered, the plugin will create an uber JAR with all required dependencies. An uber JAR is just a fat JAR that has all dependencies bundled inside itself. It also deploys our application in an in-memory Undertow server. Add the following snippet to the plugins section of the pom.xml file:
            <plugin> 
              <groupId>org.wildfly.swarm</groupId> 
              <artifactId>wildfly-swarm-plugin</artifactId> 
              <version>1.0.0.Final</version> 
              <executions> 
                <execution> 
                  <id>package</id> 
                  <goals> 
                    <goal>package</goal> 
                  </goals> 
                </execution> 
              </executions> 
            </plugin> 
    
  2. Now execute the mvn clean package command from the project's root directory, and wait for the Maven build to be successful. If you look at the logs, you can see that wildfly-swarm-plugin will create the uber JAR, which has all its dependencies. You should see something like this in your console logs:

    How to do it...

  3. After the build is successful, you will find two artifacts in the target directory of your project. The geolocation-wildfly-0.0.1-SNAPSHOT.war file is the final WAR created by the maven-war-plugin. The geolocation-wildfly-0.0.1-SNAPSHOT-swarm.jar file is the uber JAR created by the wildfly-swarm-plugin. Execute the following command in the same terminal to start your microservice:
          java -jar target/geolocation-wildfly-0.0.1-SNAPSHOT-swarm.jar
    
  4. After executing this command, you will see that Undertow has started on port number 8080, exposing the geolocation resource we created. You will see something like this:

    How to do it...

  5. Execute the following cURL command in a separate terminal window to make sure our API is exposed. The response of the command should be [], indicating there are no geolocations:
          curl http://localhost:8080/geolocation
    
  6. Now let's build the service class and finish the APIs that we started. For simplicity purposes, we are going to store the geolocations in a collection in the service class itself. In a real-time scenario, you will be writing repository classes or DAOs that talk to the database that holds your geolocations. Get the com.packt.microservices.geolocation.GeoLocationService.java interface from the previous recipe. We'll use the same interface here.
  7. Create a new class called com.packt.microservices.geolocation.GeoLocationServiceImpl.java that extends the GeoLocationService interface:
            package com.packt.microservices.geolocation; 
     
            import java.util.ArrayList; 
            import java.util.Collections; 
            import java.util.List; 
     
            public class GeoLocationServiceImpl implements
            GeoLocationService { 
       
              private static List<GeoLocation> geolocations = new 
               ArrayList<>
              (); 
     
             @Override 
              public GeoLocation create(GeoLocation geolocation) { 
                geolocations.add(geolocation); 
                return geolocation; 
              } 
     
             @Override 
              public List<GeoLocation> findAll() { 
                return Collections.unmodifiableList(geolocations); 
              } 
            } 
    
  8. Now that our service classes are implemented, let's finish building the APIs. We already have a very basic stubbed-out GET API. Let's just introduce the service class to the resource class and call the findAll method. Similarly, let's use the service's create method for POST API calls. Add the following snippet to GeoLocationResource.java:
           private GeoLocationService service = new
           GeoLocationServiceImpl(); 
     
           @GET 
           @Produces("application/json") 
           public List<GeoLocation> findAll() { 
             return service.findAll(); 
           } 
       
           @POST 
           @Produces("application/json") 
           @Consumes("application/json") 
           public GeoLocation create(GeoLocation geolocation) { 
             return service.create(geolocation); 
           } 
    
  9. We are now ready to test our application. Go ahead and build your application. After the build is successful, run your microservice: let's try to create two geolocations using the POST API and later try to retrieve them using the GET method. Execute the following cURL commands in your terminal one by one:
              curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:8080/geolocation
    
  10. This should give you something like the following output (pretty-printed for readability):
    {
              "latitude": 41.803488,
              "longitude": -88.14404,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:8080/geolocation
    
    
  11. This command should give you an output similar to the following (pretty-printed for readability):
            { 
              "latitude": 9.568012, 
              "longitude": 77.962444, 
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", 
              "timestamp": 1468203975 
            }
    
  12. To verify whether your entities were stored correctly, execute the following cURL command:
             curl http://localhost:8080/geolocation
    
  13. This should give you an output like this (pretty-printed for readability):
            [
              {
                 "latitude": 41.803488,
                 "longitude": -88.14404,
                 "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                 "timestamp": 1468203975
              },
              {
                "latitude": 9.568012,
                "longitude": 77.962444,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
              }
            ]
    

Whatever we have seen so far will give you a head start in building microservices with WildFly Swarm. Of course, there are tons of features that WildFly Swarm offers. Feel free to try them out based on your application needs. I strongly recommend going through the WildFly Swarm documentation for any advanced usages. If you already know that you are going to be using WildFly Swarm for your microservices, you can skip the rest of the recipes in this chapter and jump to next chapter. The final two recipes in this chapter will show you how to create microservices using Dropwizard and how to create RESTful APIs with SparkJava.

Writing microservices with Dropwizard

Dropwizard is a collection of libraries that help you build powerful applications quickly and easily. The libraries vary from Jackson, Jersey, Jetty, and so on. You can take a look at the full list of libraries on their website. This ecosystem of libraries that help you build powerful applications could be utilized to create microservices as well. As we saw earlier, it utilizes Jetty to expose its services. In this recipe, we will create the same GeoLocation API using Dropwizard and Jersey.

To avoid confusion and dependency conflicts in our project, we will create the Dropwizard microservice as its own Maven project. This recipe is just here to help you get started with Dropwizard. When you are building your production-level application, it is your choice to either use Spring Boot, WildFly Swarm, Dropwizard, or SparkJava based on your needs.

Getting ready

Similar to how we created other Maven projects, create a Maven JAR module with the groupId  com.packt.microservices and name/artifactId  geolocation-dropwizard. Feel free to use either your IDE or the command line. After the project is created, if you see that your project is using a Java version other than 1.8, follow the Creating a project template using STS and Maven recipe to change the Java version to 1.8. Perform a Maven update for the change to take effect.

How to do it...

The first thing that you will need is the dropwizard-core Maven dependency. Add the following snippet to your project's pom.xml file:

  <dependencies> 
    <dependency> 
      <groupId>io.dropwizard</groupId> 
      <artifactId>dropwizard-core</artifactId> 
      <version>0.9.3</version> 
    </dependency> 
  </dependencies> 

Guess what? This is the only dependency you will need to spin up a simple Jersey-based Dropwizard microservice.

Before we start configuring Dropwizard, we have to create the domain object, service class, and resource class. Follow the steps from the previous recipe to create the following four files:

  • com.packt.microservices.geolocation.GeoLocation.java
  • com.packt.microservices.geolocation.GeoLocationService.java
  • com.packt.microservices.geolocation.GeoLocationServiceImpl.java
  • com.packt.microservices.geolocation. GeoLocationResource.java

Let's see what each of these classes does. The GeoLocation.java class is our domain object that holds the geolocation information. The GeoLocationService.java class defines our interface, which is then implemented by the GeoLocationServiceImpl.java class. If you take a look at the GeoLocationServiceImpl.java class, we are using a simple collection to store the GeoLocation domain objects. In a real-time scenario, you will be persisting these objects in a database. But to keep it simple, we will not go that far.

To be consistent with the previous recipe, let's change the path of GeoLocationResource to /geolocation. To do so, replace @Path("/") with @Path("/geolocation") on line number 11 of the GeoLocationResource.java class.

We have now created the service classes, domain object, and resource class. Let's configure Dropwizard.

In order to make your project a microservice, you have to do two things:

  1. Create a Dropwizard configuration class. This is used to store any meta-information or resource information that your application will need during runtime, such as DB connection, Jetty server, logging, and metrics configurations. These configurations are ideally stored in a YAML file, which will then be mapped to your Configuration class using Jackson. In this application, we are not going to use the YAML configuration as it is out of scope for this book.

    Note

    If you would like to know more about configuring Dropwizard, refer to their Getting Started documentation page at http://www.dropwizard.io/0.7.1/docs/getting-started.html .

  2. Let's create an empty Configuration class called GeoLocationConfiguration.java:
             package com.packt.microservices.geolocation; 
     
             import io.dropwizard.Configuration; 
     
             public class GeoLocationConfiguration extends Configuration { 
     
             } 
    
  3. The YAML configuration file has a lot to offer. Take a look at a sample YAML file from Dropwizard's Getting Started documentation page to learn more. The name of the YAML file is usually derived from the name of your microservice. The microservice name is usually identified by the return value of the overridden method public String getName() in your Application class. Now let's create the GeoLocationApplication.java application class:
            package com.packt.microservices.geolocation; 
     
            import io.dropwizard.Application; 
            import io.dropwizard.setup.Environment; 
      
            public class GeoLocationApplication extends
            Application<GeoLocationConfiguration> { 
        
              public static void main(String[] args) throws Exception { 
                new GeoLocationApplication().run(args); 
              } 
     
              @Override 
              public void run(GeoLocationConfiguration config, Environment 
                 env) throws Exception { 
                 env.jersey().register(new GeoLocationResource()); 
              } 
            } 
    

    There are a lot of things going on here. Let's look at them one by one. Firstly, this class extends Application with the GeoLocationConfiguration generic. This clearly makes an instance of your GeoLocationConfiguraiton.java class available so that you have access to all the properties you have defined in your YAML file at the same time mapped in the Configuration class. The next one is the run method. The run method takes two arguments: your configuration and environment. The Environment instance is a wrapper to other library-specific objects such as MetricsRegistry, HealthCheckRegistry, and JerseyEnvironment. For example, we could register our Jersey resources using the JerseyEnvironment instance. The env.jersey().register(new GeoLocationResource()) line does exactly that. The main method is pretty straight-forward. All it does is call the run method.

  4. Before we can start the microservice, we have to configure this project to create a runnable uber JAR. Uber JARs are just fat JARs that bundle their dependencies in themselves. For this purpose, we will be using the maven-shade-plugin. Add the following snippet to the build section of the pom.xml file. If this is your first plugin, you might want to wrap it in a <plugins> element under <build>:
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>2.3</version>
          <configuration>
            <createDependencyReducedPom>true</createDependencyReducedPom>
            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
              <configuration>
                <transformers>
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
        <mainClass>com.packt.microservices.geolocation.GeoLocationApplication</mainClass>
                  </transformer>
                </transformers>
              </configuration>
            </execution>
          </executions>
        </plugin>
     
    
  5. The previous snippet does the following:

    It creates a runnable uber JAR that has a reduced pom.xml file that does not include the dependencies that are added to the uber JAR. To learn more about this property, take a look at the documentation of maven-shade-plugin.

    It utilizes com.packt.microservices.geolocation.GeoLocationApplication as the class whose main method will be invoked when this JAR is executed. This is done by updating the MANIFEST file.

    It excludes all signatures from signed JARs. This is required to avoid security errors.

  6. Now that our project is properly configured, let's try to build and run it from the command line. To build the project, execute mvn clean package from the project's root directory in your terminal. This will create your final JAR in the target directory. Execute the following command to start your microservice:
          java -jar target/geolocation-dropwizard-0.0.1-SNAPSHOT.jar server
    
  7. The server argument instructs Dropwizard to start the Jetty server. After you issue the command, you should be able to see that Dropwizard has started the in-memory Jetty server on port 8080. If you see any warnings about health checks, ignore them. Your console logs should look something like this:

    How to do it...

  8. We are now ready to test our application. Let's try to create two geolocations using the POST API and later try to retrieve them using the GET method. Execute the following cURL commands in your terminal one by one:
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:8080/geolocation
    
  9. This should give you an output similar to the following (pretty-printed for readability):
    {
              "latitude": 41.803488,
              "longitude": -88.14404,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:8080/geolocation
    
  10. This should give you an output like this (pretty-printed for readability):
    {  
              "latitude": 9.568012,
              "longitude": 77.962444,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
  11. To verify whether your entities were stored correctly, execute the following cURL command:
          curl http://localhost:8080/geolocation
    
  12. It should give you an output similar to the following (pretty-printed for readability):
    [
              {
                "latitude": 41.803488,
                "longitude": -88.14404,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
              },
              {
                "latitude": 9.568012,
                "longitude": 77.962444,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
             }
           ]
    

Excellent! You have created your first microservice with Dropwizard. Dropwizard offers more than what we have seen so far. Some of it is out of scope for this book. I believe the metrics API that Dropwizard uses could be used in any type of application. Therefore, we will look at how to use it in later chapters.

Writing REST APIs with SparkJava

In the previous recipes, we saw how to create a microservice using various frameworks such as Spring Boot, WildFly Swarm, and Dropwizard. This recipe is going to be a little different for the fact that we are going to see how to create a self-managed RESTful API using a framework called SparkJava. Not to be confused with Apache Spark, the SparkJava framework claims to be a micro-framework for building web applications. Their HTTP API was inspired by Ruby's Sinatra framework. It is so simple that bringing up an HTTP GET API requires fewer than ten lines of code. Owing to this, SparkJava is something that could be considered when you would like to quickly build HTTP-based microservices.

To avoid confusion and dependency conflicts in our project, we will create the SparkJava microservice as its own Maven project. This recipe is just here to help you get started with SparkJava. When you are building your production-level application, it is your choice to either use Spring Boot, WildFly Swarm, Dropwizard, or SparkJava based on your needs.

Getting ready

Similar to how we created other Maven projects, create a Maven JAR module with the groupId com.packt.microservices and name/artifactId geolocation-sparkjava. Feel free to use either your IDE or the command line. After the project is created, if you see that your project is using a Java version other than 1.8, follow the Creating a project template using STS and Maven recipe to change the Java version to 1.8. Perform a Maven update for the change to take effect.

How to do it...

The first thing that you will need is the SparkJava dependency. Add the following snippet to your project's pom.xml file:

  <dependencies> 
    <dependency> 
      <groupId>com.sparkjava</groupId> 
      <artifactId>spark-core</artifactId> 
      <version>2.5</version> 
    </dependency> 
  </dependencies> 

We now have to create the domain object and service class. Follow the Writing microservices with WildFly Swarm recipe to create the following three files:

  • com.packt.microservices.geolocation.GeoLocation.java
  • com.packt.microservices.geolocation.GeoLocationService.java
  • com.packt.microservices.geolocation.GeoLocationServiceImpl.java

Let's see what each of these classes does. The GeoLocation.java class is our domain object that holds the geolocation information. The GeoLocationService.java interface defines our interface, which is then implemented by the GeoLocationServiceImpl.java class. If you take a look at the GeoLocationServiceImpl.java class, we are using a simple collection to store the GeoLocation domain objects. In a real-time scenario, you will be persisting these objects in a database. But to keep it simple, we will not go that far.

The next thing that SparkJava needs is a controller. If you are familiar with Spring MVC, you can relate this controller to that of Spring MVC's. The controller has a collection of routes defined for each URL pattern in your API. Follow these steps:

  1. Let's create our controller com.packt.microservices.geolocation.GeoLocationController.java with a stubbed-out GET API:
          package com.packt.microservices.geolocation; 
     
          import static spark.Spark.*; 
     
          public class GeoLocationController { 
     
            public static void main(String[] args) { 
              get("/geolocation", (req, resp) -> "[]"); 
            } 
          } 
    
  2. The quickest way to test this is by running this class as a Java application. If you get SLF4J errors in your console after you start the application, add the following Maven dependency to your pom.xml file and restart your application:
          <dependency> 
            <groupId>org.slf4j</groupId> 
            <artifactId>slf4j-simple</artifactId> 
            <version>1.7.21</version> 
          </dependency> 
    

    The slf4j-simple dependency routes all the SLF4Jlog messages to the System.err stream.

  3. Your console logs should look something like this after the restart:

    How to do it...

    From the logs, we can clearly see that the service is running on port 4567.

  4. Execute the following curl command in a terminal window to make sure our API is exposed. The response of the following command should be [], indicating there are no geolocations:
          curl http://localhost:4567/geolocation
    
  5. Now let's finish building the APIs. We already have a very basic stubbed-out GET API. Let's just introduce the service class to the controller and call the findAll method. Similarly, let's use the service's create method for POST API calls. Before we do that, we need to do one more thing. By default, SparkJava does not perform JSON serialization and deserialization. We will be using a library called gson to do that. So add the following dependency to your pom.xml file:
            <dependency>
              <groupId>com.google.code.gson</groupId>
              <artifactId>gson</artifactId>
              <version>2.7</version>
            </dependency>
  6. Now let's replace the main method of GeoLocationController.java with this:
        public static void main(String[] args) {
          GeoLocationService service = new GeoLocationServiceImpl();
          Gson gson = new Gson();
        
          get("/geolocation", (req, resp) -> {
            return service.findAll();
          }, gson::toJson);
        
          post("/geolocation", (req, resp) -> {
            return service.create(gson.fromJson(req.body(), GeoLocation.class));
          }, gson::toJson);
        }
    

Yes, there are too many things happening here. Let's try to understand them one by one:

  • The get method now uses the service's findAll method
  • The third argument to the get method is the ResponseTransformer, which says how your response should be transformed before being sent to the client
  • Since the ResponseTransformer is a FunctionalInterface with just one method render that takes in the rendering logic as an object, we are passing the method reference to Gson's toJson method as the rendering logic here.
  • The post method, which uses the service's create method, uses Gson to transform the request body to a GeoLocation value.

We are now ready to test our application. Restart the application. Let's try to create two geolocations using the POST API and later try to retrieve them using the GET method:

  1. Execute the following cURL commands in your terminal one by one:
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:4567/geolocation
    
  2. This should give you an output similar to the following (pretty-printed for readability):
            {
              "latitude": 41.803488,
              "longitude": -88.14404,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:4567/geolocation
    
  3. This should give you an output like this (pretty-printed for readability):
            {
              "latitude": 9.568012,
              "longitude": 77.962444,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
  4. To verify whether your entities were stored correctly, execute the following cURL command:
          curl http://localhost:4567/geolocation
    
  5. It should give you output similar to the following (pretty-printed for readability):
            [
              {
                "latitude": 41.803488,
                "longitude": -88.14404,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
              },
              {
                "latitude": 9.568012,
                "longitude": 77.962444,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
              }
           ]
    

There are several other configurations that you can make to SparkJava, such as changing the default port, using query parameters, and using path parameters. I'll leave that to you to experiment.

Conclusion

At the beginning of this chapter, we quickly saw an overview of what microservices are and how they benefit organizations by making it easier to manage and deploy independent services. We looked at an example of a geolocation tracker application to see how it can be broken down into smaller and manageable services. Next, we saw how to create the GeoLocationTracker service using the Spring Boot framework. We also learned how to expose our APIs that consume and read geolocations using Spring MVC. Next, we saw how to build the same application using WildFly Swarm, and JAX-RS. Later, we built the same application using Dropwizard. Finally, we saw how to implement the same service using the SparkJava framework.

I hope you now have a good understanding of what microservices are and how to create them using your favorite framework. The choice of framework completely depends on your needs and your current ecosystem. We strongly recommend you evaluate them before picking one. In the next chapter, we will learn how to package this microservice and later containerize it using Docker.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Adopt microservices-based architecture and deploy it at scale
  • Build your complete microservice architecture using different recipes for different solutions
  • Identify specific tools for specific scenarios and deliver immediate business results, correlate use cases, and adopt them in your team and organization

Description

This book will help any team or organization understand, deploy, and manage microservices at scale. It is driven by a sample application, helping you gradually build a complete microservice-based ecosystem. Rather than just focusing on writing a microservice, this book addresses various other microservice-related solutions: deployments, clustering, load balancing, logging, streaming, and monitoring. The initial chapters offer insights into how web and enterprise apps can be migrated to scalable microservices. Moving on, you’ll see how to Dockerize your application so that it is ready to be shipped and deployed. We will look at how to deploy microservices on Mesos and Marathon and will also deploy microservices on Kubernetes. Next, you will implement service discovery and load balancing for your microservices. We’ll also show you how to build asynchronous streaming systems using Kafka Streams and Apache Spark. Finally, we wind up by aggregating your logs in Kafka, creating your own metrics, and monitoring the metrics for the microservice.

Who is this book for?

This book is for developers, ops, and DevOps professionals who would like to put microservices to work and improve products, services, and operations. Those looking to build and deploy microservices will find this book useful, as well as managers and people at CXO level looking to adopt microservices in their organization. Prior knowledge of Java is expected. No prior knowledge of microservices is assumed.

What you will learn

  • Build microservices using Spring Boot, Wildfly Swarm, Dropwizard, and SparkJava
  • Containerize your microservice using Docker
  • Deploy microservices using Mesos/Marathon and Kubernetes
  • Implement service discovery and load balancing using Zookeeper, Consul, and Nginx
  • Monitor microservices using Graphite and Grafana
  • Write stream programs with Kafka Streams and Spark
  • Aggregate and manage logs using Kafka
  • Get introduced to DC/OS, Docker Swarm, and YARN
Estimated delivery fee Deliver to Ecuador

Standard delivery 10 - 13 business days

$19.95

Premium delivery 3 - 6 business days

$40.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jan 31, 2017
Length: 378 pages
Edition : 1st
Language : English
ISBN-13 : 9781786469434
Languages :
Concepts :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Ecuador

Standard delivery 10 - 13 business days

$19.95

Premium delivery 3 - 6 business days

$40.95
(Includes tracking information)

Product Details

Publication date : Jan 31, 2017
Length: 378 pages
Edition : 1st
Language : English
ISBN-13 : 9781786469434
Languages :
Concepts :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 164.97
Spring 5.0 Microservices
$54.99
Mastering Kubernetes
$54.99
Microservices Deployment Cookbook
$54.99
Total $ 164.97 Stars icon
Banner background image

Table of Contents

8 Chapters
1. Building Microservices with Java Chevron down icon Chevron up icon
2. Containerizing Microservices with Docker Chevron down icon Chevron up icon
3. Deploying Microservices on Mesos Chevron down icon Chevron up icon
4. Deploying Microservices on Kubernetes Chevron down icon Chevron up icon
5. Service Discovery and Load Balancing Microservices Chevron down icon Chevron up icon
6. Monitoring Microservices Chevron down icon Chevron up icon
7. Building Asynchronous Streaming Systems with Kafka and Spark Chevron down icon Chevron up icon
8. More Clustering Frameworks - DC/OS, Docker Swarm, and YARN Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.8
(6 Ratings)
5 star 50%
4 star 16.7%
3 star 16.7%
2 star 0%
1 star 16.7%
Filter icon Filter
Top Reviews

Filter reviews by




Amazon Customer Jun 28, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very good book
Amazon Verified review Amazon
TR Jordan Nov 06, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This is a solid, practical guide to implementing common patterns around microservices in 2017.You'll probably only use 10% of the recipes in this book, and that's by design. Murugesan lays out the common structures that you'll need to build, and each of the recipes is a practical, examples-in-code guide to wiring up particular technologies. Every system is different enough that he leaves the tech choices to the reader, without sacrificing the specificity to actually get something working.Definitely worth having around if you're transitioning to microservices or scaling out an existing architecture.
Amazon Verified review Amazon
James Aug 29, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This is the best micro service book. I was learning docker and going through docker, microservice books. Most of the books are one dimensional and provide limited knowledge. But this book touched lot of topics and provides excellent explanation. Thank you.
Amazon Verified review Amazon
Raman Kr. Rai Sep 14, 2018
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Nice book, Love it.
Amazon Verified review Amazon
Richard Sep 14, 2017
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
It is a decent book. There are many recipes that I could not following through due to errors.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact [email protected] with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at [email protected] using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on [email protected] with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on [email protected] within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on [email protected] who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on [email protected] within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela