1. CACHING USING RESTTEMPLATE, EHCAHE AND ETAGS
Often times I have seen API implementations not taking advantage of client side caching. Consider this example, a REST service needs to get data from a handful of other services and for every request, even though the upstream response might have not changed for the same input, it’s being calculated repeatedly and sent back to the client.
Depending on how expensive this calculation might be, wouldn’t be a better approach if the HTTP request includes data about what it previously has stored from a prior server response in an attempt for the server to find out if this calculation would be needed at all? This will improve the application performance while saving on server resources.
And what about if this expensive calculation is not needed, wouldn’t be a good practice for the server to let the client know that nothing has changed on the server side for that request? This will also save on bandwidth, assuming the client service is able to reconstruct the response payload.
This post focuses on the client side of this improvement, configuring Spring’s RestTemplate to use HttpClient and Ehcache to cache upstream HTTP responses using ETags.
1. IMPLEMENTING A CUSTOM SPRING BOOT STARTER FOR CXF AND SWAGGER
Consider this scenario, the development team has increased over the last few years, software releases and deployment takes more time, that quick fix or feature couldn’t be delivered this Sprint because the deliverable now includes many changes that haven’t been signed off by QA and it might take another month to do so.
This seems like a good opportunity to break up the big Java monolithic application into multiple services or for that legacy set of applications in which business logic is duplicated to be refactored or rewritten, each by a small team benefiting from more frequent releases, easier to understand a small piece of functionality, having a low impact on other services, promoting ownership and accountability, etc..
Assuming for instance, it has been decided to implement the APIs using Spring Boot, Apache CXF and Swagger along with logging, metrics, security, etc. and maybe packaging the service in a Docker image, how do we setup this up for a dozen or more services? Do we create a baseline project to be copied and pasted for each service? Do we create a custom Maven archetype? What are other options?
This post covers how to create a custom Spring Boot starter for Apache CXF 3.1.x and Swagger 2 as the starting point to create services with a common set of dependencies and functionality also providing Spring beans auto-configuration to reduce explicit beans definition.
1. IMPLEMENTING APIs USING SPRING BOOT, CXF AND SWAGGER
A while back I published a blog post about Microservices using Spring Boot, Jersey, Swagger and Docker that takes advantage of the Spring ecosystem and a JAX-RS implementation in Jersey 2. In another post, Services Registration and Discovery using Eureka, Ribbon and Feign I also mentioned that Jersey 2-based endpoints attempting to register with Spring Cloud Netflix Eureka registry failed due to the fact that Eureka and Ribbon clients bring in Jersey 1 dependencies and thus conflicting with Jersey 2’s.
Instead some endpoints were implemented using Jersey 1 successfully registering with Eureka but the downside was it required configuring Jersey 1 in a multi-module Maven setup because there is no Spring Boot starter for Jersey 1 and a limitation to scan nested jars.
In this follow up post I plan to demonstrate how to integrate Apache CXF 3.1.x JAX-RS-based endpoints implementation with Spring Boot and documenting them using Swagger. The services following this setup should be able to register with Spring Cloud Netflix Eureka since no Jersey dependency would be transitively included.
1. MULTI-VERSION SERVICE DISCOVERY USING SPRING CLOUD NETFLIX EUREKA AND RIBBON
As services evolve over time, changes are made to the domain that very-likely require API versioning to prevent breaking backwards compatibility.
Unless you work in a very controlled environment, for instance, where it’s known that client applications are also distributed with the API services and there is no possibility of an old client using newer API services deployment, I’m a firm believer you should never break backwards compatibility.
I’ll say it again because this is very important, you should never break backwards compatibility, if you do, customers and partners get very angry and fixing it afterwards normally requires more effort than versioning from the beginning.
The question now is, how does versioning work in a microservice architecture where services are registered with and discovered using a Discovery infrastructure microservice such as Netflix Eureka?
In this post I’ll explain how to register and discover multiple version of a service using Spring Cloud Netflix Eureka and Ribbon.
1. REFRESHABLE CONFIGURATION USING SPRING CLOUD CONFIG SERVER, SPRING CLOUD BUS, RABBITMQ AND GIT
This post is a continuation of Centralized and versioned configuration using Spring Cloud Config Server and Git where I covered the Spring Cloud Config server to prevent hard-coding properties that most-likely would be different for each deployment environment.
At the end of said post I outlined how updating a Git-backed property and sending a POST request to the client application’s
/refresh actuator endpoint caused the configuration property to be reloaded and the dependent Spring beans to be refreshed picking up the new value.
But what if it’s not just one or two microservices but maybe dozens or even hundreds that would need to reload those properties changes? Hitting
/refresh for each one doesn’t seem like an elegant solution. What if the numbers of instances keep growing?
In this post I’ll extend the Spring Cloud Config Server and the client service implemented in part 1 with Spring Cloud Bus and RabbitMQ support and a Bitbucket webhook to automatically notify subscribed client services of changes in the Git-backed configuration files.
1. MULTI-TENANT APPLICATIONS USING SPRING BOOT, JPA, HIBERNATE AND POSTGRES
Multitenancy is an approach in which an instance of an application is used by different customers and thus dropping software development and deployment costs when compared to a single-tenant solution where multiple parts would need to be touched in order to provision new clients or update existing tenants.
There are multiple well known strategies to implement this architecture, ranging from highly isolated (like single-tenant) to everything shared.
In this post I’ll review configuring and implementing a multitenancy solution with multiple databases and one API service using Spring Boot, JPA, Hibernate and Postgres.
1. TROUBLESHOOTING SPRING RESTTEMPLATE REQUESTS TIMEOUT
Spring’s RestTemplate is one of the options to make client HTTP requests to endpoints, it facilitates communication with the HTTP servers, handles the connections and transforms the XML, JSON, … request / response payloads to / from POJOs via HttpMessageConverter.
By default RestTemplate doesn’t use a connection pool to send requests to a server, it uses a SimpleClientHttpRequestFactory that wraps a standard JDK’s HttpURLConnection taking care of opening and closing the connection.
But what if an application needs to send a large number of requests to a server? Wouldn’t it be a waste of efforts to open and close a connection for each request sent to the same host? Wouldn’t it make sense to use a connection pool the same way a JDBC connection pool is used to interact with a DB or a thread pool is used to execute tasks concurrently?
In this post I’ll cover configuring RestTemplate to use a connection pool using a pooled-implementation of the ClientHttpRequestFactory interface, run a load test using JMeter, troubleshoot requests timeout and reconfigure the connection pool.
1. CONFIGURING TOMCAT TO LISTEN ON MULTIPLE PORTS USING SPRING BOOT
Today I landed in a stackoverflow question about how to access the JavaMelody UI using a port other than the one used by the APIs. I went ahead I answered the question with some initial code I had for another blog post I’m working on but then decided to make it its own post.
While this could certainly be accomplished adding a couple of Spring Boot configuration properties: management.context-path and management.port to
application.yml for instance, and reuse the same path used for actuator endpoints (
/admin/health, …), there might be some cases where having the servlet container listening on a port other that the two mentioned earlier might make sense, maybe for monitoring, traffic analysis, firewall rules, etc..
In this post I’ll add support for configuring embedded Tomcat to listen on multiple ports and configure JavaMelody to exclusively use one of those ports to display its reports using Spring Boot.
1. CENTRALIZED AND VERSIONED CONFIGURATION USING SPRING CLOUD CONFIG SERVER AND GIT
The previous blog post covered Service Registration and Discovery as an infrastructure service used in a microservice architecture. In this post I’ll review another infrastructure microservice, the Configuration management service.
Configuration is used to prevent hard-coding values in the applications. But it’s also used to specify what is expected to be different between deployment environments (qa, staging, production, …) such as host names, mail and database credentials and other backing services. The latter type of configuration is identified as one of the elements in The Twelve-Factor App.
The benefits of this practice are that it promotes building only one artifact, only one binary to be executed in all the environments. You should never have to build a different executable for each environment, this will most-likely cause troubleshooting and debugging headaches.
As part of the Spring Cloud Series, this post describes the Spring Cloud Config’s server and client usage, the configuration storage options and its relation with the Discovery Server in a registration-first and configuration-first approaches.
1. MICROSERVICES REGISTRATION AND DISCOVERY USING SPRING CLOUD, EUREKA, RIBBON AND FEIGN
This blog post reviews an implementation pattern used in microservice architectural style: Service Registration and Discovery. The Discovery service and Configuration service, the latter discussed in this post, are most-likely the first infrastructure microservices needed when implementing such architecture.
Why is the Discovery service needed in a microservice architecture? Because if a running instance of service X needs to send requests to a running instance of service Y, it first needs to know the host and port service Y runs and listens on. One might think that service X may know this information via some static configuration file but this approach doesn’t sound very practical in an elastic-like distributed setup where services are dynamically (de)provisioned, triggered either manually or by some condition such as an auto-scaling policy or failure for instance.
Continuing with the Spring Cloud Series covered in this blog, this post discusses Spring Cloud Netflix’s Service Discovery component, a Spring-friendly and embedded Eureka server where services instances can register with and clients can discover such instances.