Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Microservices with Spring Boot 3 and Spring Cloud, Third Edition - Third Edition

You're reading from  Microservices with Spring Boot 3 and Spring Cloud, Third Edition - Third Edition

Product type Book
Published in Aug 2023
Publisher Packt
ISBN-13 9781805128694
Pages 706 pages
Edition 3rd Edition
Languages
Author (1):
Magnus Larsson Magnus Larsson
Profile icon Magnus Larsson

Table of Contents (26) Chapters

Preface 1. Introduction to Microservices 2. Introduction to Spring Boot 3. Creating a Set of Cooperating Microservices 4. Deploying Our Microservices Using Docker 5. Adding an API Description Using OpenAPI 6. Adding Persistence 7. Developing Reactive Microservices 8. Introduction to Spring Cloud 9. Adding Service Discovery Using Netflix Eureka 10. Using Spring Cloud Gateway to Hide Microservices behind an Edge Server 11. Securing Access to APIs 12. Centralized Configuration 13. Improving Resilience Using Resilience4j 14. Understanding Distributed Tracing 15. Introduction to Kubernetes 16. Deploying Our Microservices to Kubernetes 17. Implementing Kubernetes Features to Simplify the System Landscape 18. Using a Service Mesh to Improve Observability and Management 19. Centralized Logging with the EFK Stack 20. Monitoring Microservices 21. Installation Instructions for macOS 22. Installation Instructions for Microsoft Windows with WSL 2 and Ubuntu 23. Native-Complied Java Microservices 24. Other Books You May Enjoy
25. Index

Using the persistence layer in the service layer

In this section, we will learn how to use the persistence layer in the service layer to store and retrieve data from a database. We will go through the following steps:

  1. Logging the database connection URL
  2. Adding new APIs
  3. Calling the persistence layer from the service layer
  4. Declaring a Java bean mapper
  5. Updating the service tests

Logging the database connection URL

When scaling up the number of microservices where each microservice connects to its own database, it can be hard to keep track of what database each microservice actually uses. To avoid this confusion, a good practice is to add a log statement directly after the startup of a microservice that logs connection information that is used to connect to the database.For example, the startup code for the product service looks like this:

public class ProductServiceApplication {
  private static final Logger LOG = 
  LoggerFactory.getLogger(ProductServiceApplication.class);
  public...

Extending the composite service API

In this section, we will see how we can extend the composite API with operations for creating and deleting composite entities. We will go through the following steps:

  1. Adding new operations in the composite service API
  2. Adding methods in the integration layer
  3. Implementing the new composite API operations
  4. Updating the composite service tests

Adding new operations in the composite service API

The composite versions of creating and deleting entities and handling aggregated entities are similar to the create and delete operations in the core service APIs. The major difference is that they have annotations added for OpenAPI-based documentation. For an explanation of the usage of the OpenAPI annotations @Operation and @ApiResponse, refer to Chapter 5, Adding an API Description Using OpenAPI, specifically the Adding API-specific documentation to the ProductCompositeService interface section.The API operation for creating a composite product entity is declared...

Adding databases to the Docker Compose landscape

Now, we have all of the source code in place. Before we can start up the microservice landscape and try out the new APIs together with the new persistence layer, we must start up some databases.We will bring MongoDB and MySQL into the system landscape controlled by Docker Compose and add configuration to our microservices so that they can find their databases when running.

The Docker Compose configuration

MongoDB and MySQL are declared as follows in the Docker Compose configuration file, docker-compose.yml:

  mongodb:
    image: mongo:6.0.4
    mem_limit: 512m
    ports:
      - "27017:27017"
    command: mongod
    healthcheck:
      test: "mongo --eval 'db.stats().ok'"
      interval: 5s
      timeout: 2s
      retries: 60
  mysql:
    image: mysql:8.0.32
    mem_limit: 512m
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=rootpwd
      - MYSQL_DATABASE=review-db
  ...

Manual tests of the new APIs and the persistence layer

Now, we have everything in place to test the microservices together. We will build new Docker images and start up the system landscape using Docker Compose based on the Docker images. Next, we will use the Swagger UI viewer to run some manual tests. Finally, we will use the database CLI tools to see what data was inserted into the databases.Build and start the system landscape with the following command:

cd $BOOK_HOME/Chapter06
./gradlew build && docker-compose build && docker-compose up

Open Swagger UI in a web browser, http://localhost:8080/openapi/swagger-ui.html, and perform the following steps on the web page:

  1. Click on the ProductComposite service and the POST method to expand them
  2. Click on the Try it out button and go down to the body field
  3. Replace the default value, 0, of the productId field with 123456
  4. Scroll down to the Execute button and click on it
  5. Verify that the returned response code is 200

The following...

Updating the automated tests of the microservice landscape

The automated tests of the microservice landscape, test-em-all.bash, need to be updated so that they ensure that the database of each microservice has a known state before it runs the tests.The script is extended with a setup function, setupTestdata(), which uses the composite's create and delete APIs to set up test data used by the tests.The setupTestdata function looks like this:

function setupTestdata() {
    body=\
    '{"productId":1,"name":"product 1","weight":1, "recommendations":[
        {"recommendationId":1,"author":"author 
         1","rate":1,"content":"content 1"},
        {"recommendationId":2,"author":"author 
         2","rate":2,"content":"content 2"},
        {"recommendationId":3,"author":"author 
     ...

Summary

In this chapter, we have seen how we can use Spring Data to add a persistence layer to the core microservices. We used the core concepts of Spring Data, repositories, and entities to store data in both MongoDB and MySQL. The programming model is similar for a NoSQL database such as MongoDB and a SQL database such as MySQL, even though it's not fully portable. We have also seen how Spring Boot's annotations, @DataMongoTest and @DataJpaTest, can be used to conveniently set up tests targeted for persistence; this is where a database is started automatically before the test runs, but no other infrastructure that the microservice will need at runtime, for example, a web server such as Netty, is started up. To handle the startup and teardown of databases, we have used Testcontainers, which runs the databases in Docker containers. This results in persistence tests that are easy to set up and that start with minimum overhead.We have also seen how the persistence layer can be...

Questions

  1. Spring Data, a common programming model based on entities and repositories, can be used for different types of database engines. From the source code examples in this chapter, what are the most important differences in the persistence code for MySQL and MongoDB?
  2. What is required to implement optimistic locking using Spring Data?
  3. What is MapStruct used for?
  4. What does it mean if an operation is idempotent and why is that useful?
  5. How can we access the data that is stored in the MySQL and MongoDB databases without using the API?

Summary

In this chapter, we have seen how we can develop reactive microservices!

Using Spring WebFlux and Spring WebClient, we can develop non-blocking synchronous APIs that can handle incoming HTTP requests and send outgoing HTTP requests without blocking any threads. Using Spring Data’s reactive support for MongoDB, we can also access MongoDB databases in a non-blocking way, that is, without blocking any threads while waiting for responses from the database. Spring WebFlux, Spring WebClient, and Spring Data rely on Project Reactor to provide their reactive and non-blocking features. When we must use blocking code, for example, when using Spring Data for JPA, we can encapsulate the processing of the blocking code by scheduling the processing of it in a dedicated thread pool.

We have also seen how Spring Data Stream can be used to develop event-driven asynchronous services that work on both RabbitMQ and Kafka as messaging systems without requiring any changes in the...

Questions

  1. Why is it important to know how to develop reactive microservices?
  2. How do you choose between non-blocking synchronous APIs and event-/message-driven asynchronous services?
  3. What makes an event different from a message?
  4. Name some challenges with message-driven asynchronous services. How do we handle them?
  5. Why is the following test not failing?
    @Test
    void testStepVerifier() {
      StepVerifier.create(Flux.just(1, 2, 3, 4)
        .filter(n -> n % 2 == 0)
        .map(n -> n * 2)
        .log())
        .expectNext(4, 8, 12);
    }
    

    First, ensure that the test fails. Next, correct the test so that it succeeds.

  1. What are the challenges of writing tests with reactive code using JUnit, and how can we handle them?
lock icon The rest of the chapter is locked
You have been reading a chapter from
Microservices with Spring Boot 3 and Spring Cloud, Third Edition - Third Edition
Published in: Aug 2023 Publisher: Packt ISBN-13: 9781805128694
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}