Java Microservices with Spring Boot and Spring Cloud

Java Microservices with Spring Boot and Spring Cloud

This tutorial shows you how to build a microservices architecture with Spring Boot and Spring Cloud.

Gregg Zahn

Kinda messy. I think the best approach is using JWT and validate the token in the gateway if downstream microservices are secure. If not secure, add token validation in a filter in each microservice.

Matt Raible

Yep! That’s what the code in this tutorial does.

George Kofi

Thanks again Matt for this nice piece. I have a question though, how do I implement logout functionality in this sample.
Thanks

Matt Raible

Hello George - I wrote another tutorial that covers logout. See its Logout with OAuth 2.0 and OIDC section for code you can use to implement logout on the client.

Unfortunately, server-side logout is not yet possible. Follow our Spring Boot Starter’s issue 126 for more info.

SaNtu Yadav

where is the “/cars” endpoint in car-service so that FeignClient will call to fetch data
and how FetchClient works, if you can explain to me i will be thankfull to you
my e-mail: info.santu1993@gmail.com

Matt Raible

It’s created by the RepositoryRestResource annotation. This annotation creates REST endpoints for you to CRUD the entity it manages.

Dean Schulze

On Ubuntu-19.04 httpie gave me an error:

$ http https://start.spring.io/sta… javaVersion==11 artifactId==discovery-service name==eureka-service dependencies==cloud-eureka-server baseDir==discovery-service | tar -xzvf -
gzip: stdin has more than one entry–rest ignored
tar: Child returned status 2
tar: Error is not recoverable: exiting now

Dean Schulze

Solved this by replacing

| tar -xzvf -

with

-o discovery.zip

Dean Schulze

Can you please explain what is happening with this:


@Bean
ApplicationRunner init(CarRepository repository) {
return args -> {
Stream.of(“Ferrari”, “Jaguar”, “Porsche”, “Lamborghini”, “Bugatti”,
“AMC Gremlin”, “Triumph Stag”, “Ford Pinto”, “Yugo GV”).forEach(name -> {
repository.save(new Car(name));
});
repository.findAll().forEach(System.out::println);
};
}

How does this return an ApplicationRunner?

pavan kumar

He is inserting some fake data and ensuring that they are present in DB by printing them out using Db query. ApplicationRunner requires the user to implement just one method. Author just did that by using a lambda.

Dean Schulze

I understand what he is doing with the repository, but what is he doing with the args variable which is of type org.springframework.boot.ApplicationArguments?

Java allows providing a lambda in place of a SAM (single abstract method) class instance. Is that what he’s doing or is this some Java 11 magic?

Dean Schulze

Finding more mysteries with this code construct. If I put this statement before the return statement I get a compile error:

ApplicationArguments args_ = args;

The javac cannot find the symbol args. And before adding this statement there was no import for ApplicationArguments.

Dean Schulze

When I run the cloned source code under JDK 11 I get an empty array for localhost:8080/cool-cars. The localhost:8080/cars and localhost:8080/home work, though.

The only change I made was to the two application.properties files where I used my okta.oauth2 URL and credentials.

Can anyone confirm that this problem is caused by JDK 11?

Matt Raible

I’ve seen this behavior as well. The first time I hit /cool-cars, it returns an empty array. If I refresh my browser, it populates as expected. I’m not sure why this happens.

Marc-Arthur Pierre-Louis

I am experiencing the same problem. I set a breakpoint in the goodCars() method in the api gateway in an Eclipse debugger and saw that a Collection of empty car objects was being returned. So I added a getter in the car-service application and verified that a collection of valid cars was being returned in the goodCars method and yet I was still getting am empty list in the browser. This led me to think that the fallback method was being hit all the time. So I disabled Hystrix , first in the code (commented it out) and I got a valid list in the browser. I also disabled Hystrix in application.properties while leaving the Hystrrix annotatiom intact in the code. I also got a valid list in the browser. In debugging this my breakpoint would be hit and I would see that the empty list is already returned without me stepping through the code. This leads me to think that there is a synchronization problem where the fallback is hit while the goodCars method is also hit.

I am curious if anybody has seen this strange behavior.

Shanika Wijerathna

Hi Matt, Thanks for the great blog. Spring Security will use HttpSession to store the access token which makes the application depend on http session state right? If we deploy that in an environment like kubernetes where you will have multiple instances of the app (Or gateway) it will not work since the session is not shared. What approach would you recommend to solve that problem? Going for implicit flow, or issue a separate JWT token to maintain user data? Highly appreciate any input. Thanks

Matt Raible

If you use oauth2Login() with Spring Security, yes, it will store the access token in the session. If you setup your Spring Boot app as a resource server, it will validate the JWT and act in a stateless manner. If you’re using multiple instances of your app with oauth2Login(), I’d recommend you use something like Spring Session and back it with Redis or Hazelcast.

Matt Raible

There’s no Java 11 magic in this code. It’s just Java 8 lambdas.

Shanika Wijerathna

Thanks Matt!