Reader small image

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

Product typeBook
Published inAug 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781805128694
Edition3rd Edition
Languages
Right arrow
Author (1)
Magnus Larsson
Magnus Larsson
author image
Magnus Larsson

Magnus Larsson, an IT industry veteran since 1986, has consulted for major Swedish firms like Volvo, Ericsson, and AstraZeneca. Despite past struggles with distributed systems, today's open-source tools like Spring Cloud, Kubernetes, and Istio offer effective solutions. For the past eight years, Magnus has been helping customers use these tools and shared insights through presentations and blog posts.
Read more about Magnus Larsson

Right arrow

Introduction to using springdoc-openapi

springdoc-openapi makes it possible to keep the documentation of the API together with the source code that implements the API. springdoc-openapi can create the API documentation on the fly at runtime by inspecting Java annotations in the code. To me, this is an important feature. If the API documentation is maintained in a separate life cycle from the Java source code, they will diverge from each other over time. In many cases, this will happen sooner than expected (based on my own experience).

Before springdoc-openapi was created, another open source project, SpringFox (http://springfox.github.io/springfox/), provided similar features. Over recent years, the SpringFox project has not been actively maintained and, as a reaction to that, the springdoc-openapi project was created. A migration guide for SpringFox users can be found at https://springdoc.org/#migrating-from-springfox.

As always, it is important to separate the interface of a component...

Adding springdoc-openapi to the source code

To add OpenAPI-based documentation regarding the external API that's exposed by the product-composite-service microservice, we need to change the source code in two projects:

  • product-composite-service: Here, we will set up a configuration of springdoc-openapi in the Java application class, ProductCompositeServiceApplication, and describe general information pertaining to the API.
  • api: Here, we will add annotations to the Java interface, ProductCompositeService, describing each RESTful service and its operations. At this stage, we only have one RESTful service with one operation, accepting HTTP GET requests to /product-composite/{productId}, which is used for requesting composite information regarding a specific product.

The actual texts that are used to describe the API operation will be placed in the default property file, application.yml, in the product-composite-service project.Before we can start using springdoc-openapi, we need to...

Building and starting the microservice landscape

Before we can try out the OpenAPI documentation, we need to build and start the microservice landscape!This can be done with the following commands:

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

You may run into an error message regarding port 8080 already being allocated. This will look as follows:

ERROR: for product-composite Cannot start service product-composite: driver failed programming external connectivity on endpoint chapter05_product-composite_1 (0138d46f2a3055ed1b90b3b3daca92330919a1e7fec20351728633222db5e737): Bind for 0.0.0.0:8080 failed: port is already allocated

If this is the case, you might have forgotten to bring down the microservice landscape from the previous chapter. To find out the names of the executing containers, run the following command:

 docker ps --format {{.Names}}

A sample response when a microservice landscape from the previous chapter is still...

Trying out the OpenAPI documentation

To browse the OpenAPI documentation, we will use the embedded Swagger UI viewer. If we open the http://localhost:8080/openapi/swagger-ui.html URL in a web browser, we will see a web page that looks something like the following screenshot:

Figure 5.2: OpenAPI documentation with the Swagger UI viewer

Here, we can ascertain the following:

  1. The general information we specified in the springdoc-openapi OpenAPI bean and a link to the actual OpenAPI document, /openapi/v3/api-docs, pointing to http://localhost:8080/openapi/v3/api-docs.

    Note that this is the link to the OpenAPI document that can be exported to an API Gateway, as discussed in the Introduction to using springdoc-openapi section above.

  2. A list of API resources; in our case, the ProductComposite API.
  3. At the bottom of the page, there is a section where we can inspect the schemas used in the API.

Proceed with the examination of the API documentation as follows:

  1. Click on the ProductComposite...

Summary

Good documenting of an API is essential for its acceptance, and OpenAPI is one of the most commonly used specifications when it comes to documenting RESTful services. springdoc-openapi is an open source project that makes it possible to create OpenAPI-based API documentation on the fly at runtime by inspecting Spring WebFlux and Swagger annotations. Textual descriptions of an API can be extracted from the annotations in the Java source code and be placed in a property file for ease of editing. springdoc-openapi can be configured to bring in an embedded Swagger UI viewer into a microservice, which makes it very easy to read about APIs that have been exposed by the microservice and also try them out from the viewer.Now, what about bringing some life to our microservices by adding persistence, that is, the capability to save their data in a database? To do this, we also need to add some more APIs so that we can create and delete the information that's handled by the microservices...

Questions

  1. How does springdoc-openapi help us create API documentation for RESTful services?
  2. What specification for documenting APIs does springdoc-openapi support?
  3. What is the purpose of the springdoc-openapi OpenAPI bean?
  4. Name some annotations that springdoc-openapi reads at runtime to create the API documentation on the fly.
  5. What does the code ": |" mean in a YAML file?
  6. How can you repeat a call to an API that was performed using the embedded Swagger UI viewer without using the viewer again?

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 to the composite service API
  2. Adding methods to the integration layer
  3. Implementing the new composite API operations
  4. Updating the composite service tests

Adding new operations to 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...

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...

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. ...

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 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 saw 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 also saw 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?
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 2023Publisher: PacktISBN-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.
undefined
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

Author (1)

author image
Magnus Larsson

Magnus Larsson, an IT industry veteran since 1986, has consulted for major Swedish firms like Volvo, Ericsson, and AstraZeneca. Despite past struggles with distributed systems, today's open-source tools like Spring Cloud, Kubernetes, and Istio offer effective solutions. For the past eight years, Magnus has been helping customers use these tools and shared insights through presentations and blog posts.
Read more about Magnus Larsson