This Spring Boot App Thinks! Google Gemini + Config Server + API Gateway

Rudra NarayanRudra Narayan
4 min read

Recently, I integrated AI capabilities into my Spring Boot microservices project using Google's Gemini API. Along the way, I also added a Spring Cloud Config Server to manage all my service configurations in one place, and an API Gateway for clean routing โ€” so I don't have to call services using messy port numbers anymore.

In this article, I will walk you through:

  • How I integrated Gemini AI into a microservice

  • How I centralized all application.properties using Config Server

  • How I used Spring Cloud Gateway to route all requests

  • Problems I faced and how I solved them


Step 1: Integrating Gemini AI into a Microservice

I created a dedicated ai-service to handle all AI logic.

๐Ÿ”น Goal:

Use Google Gemini to provide smart, AI-powered fitness recommendations based on user activity data.

๐Ÿ”น What I Did:

  • Created a REST controller with the /api/recommendations endpoint.

  • Used a controller class to call the Gemini API.

  • Stored the Gemini API Key and URL as external configuration using placeholders (${GEMINI_API_KEY}, ${GEMINI_API_URL}).

๐Ÿ”น Sample Code:

package com.fitness.aiservice.controller;

import com.fitness.aiservice.model.Recommendation;
import com.fitness.aiservice.service.RecommendationService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/recommendations")
public class RecommendationController {
    private final RecommendationService recommendationService;

    @GetMapping("/user/{userId}")
    public ResponseEntity<List<Recommendation>> getUserRecommendation(@PathVariable String userId) {
        return ResponseEntity.ok(recommendationService.getUserRecommendation(userId));
    }

    @GetMapping("/activity/{activityId}")
    public ResponseEntity<Recommendation> getActivityRecommendation(@PathVariable String activityId) {
        return ResponseEntity.ok(recommendationService.getActivityRecommendation(activityId));
    }
}

๐Ÿ—๏ธ Step 2: Centralizing Configuration with Spring Cloud Config Server

Instead of managing multiple application.properties files across microservices, I set up a Spring Cloud Config Server to keep everything centralized and manageable.

๐Ÿ”น What I Did:

  • Created a new microservice called config-server

  • Stored all microservice configs (user-service.properties, ai-service.properties, etc.) in one folder (/config)

  • Added placeholder values like ${GEMINI_API_KEY} to be resolved at runtime

๐Ÿ”น Config Server Setup:

spring.application.name=config-server
spring.profiles.active=native
spring.cloud.server.native.search-locations=classpath:/config
server.port=8888

Now all services fetch their configs from the Config Server using:

spring.application.name=user-service
spring.config.import=optional:configserver:http://localhost:8888

This removed redundancy and made my project cleaner and production-ready.


๐ŸŒ Step 3: Routing All Services Through API Gateway

Calling individual services on ports like 8081, 8082, 8083 felt messy, especially as the number of services grew. So I added an API Gateway.

๐Ÿ”น What I Did:

  • Used Spring Cloud Gateway to route all traffic

  • Registered all services with Eureka Discovery Server

  • Added clean routes in api-gateway so I could call everything from a single port

๐Ÿ”น Gateway Configuration:

spring.application.name=api-gateway

# Server port
server.port=8080

logging.level.org.springframework.cloud.gateway=DEBUG
logging.level.reactor.netty=INFO
logging.level.org.springframework.web=DEBUG

# Eureka client
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

# Spring Cloud Gateway Routes
spring.cloud.gateway.routes[0].id=USER-SERVICE
spring.cloud.gateway.routes[0].uri=lb://USER-SERVICE
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**

spring.cloud.gateway.routes[1].id=activity-service
spring.cloud.gateway.routes[1].uri=lb://ACTIVITY-SERVICE
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/activities/**

spring.cloud.gateway.routes[2].id=ai-service
spring.cloud.gateway.routes[2].uri=lb://AI-SERVICE
spring.cloud.gateway.routes[2].predicates[0]=Path=/api/recommendations/**

โ— Problems I Faced (and Fixed)

๐Ÿ”ด 1. Spring Cloud Gateway Dependency Deprecated

Initially, I used:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

But it failed with errors related to missing WebFlux or TransportClientFactories.

โœ… Fix:
I replaced it with the proper WebFlux dependency and ensured spring-boot-starter-webflux was present (Spring Cloud Gateway is reactive).

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

๐Ÿ”ด 2. Service Not Found (404 from Gateway)

Even after setting up Eureka and Gateway, I was getting 404 NOT_FOUND.

โœ… Fix:
I discovered that the microservices were registering themselves in Eureka using the machine hostname (e.g., LAPTOP-XXXX.mshome.net), which the API Gateway couldn't resolve properly. To address this, I configured each service to register with localhost instead.

This ensured proper service discovery and allowed the API Gateway to route requests seamlessly.


โœ… Results

Now I can:

  • ๐Ÿ” Call any microservice from a single port (8080) via Gateway

  • ๐Ÿ” Securely manage all configuration values from one place

  • ๐Ÿค– Use Gemini API to generate AI-based recommendations


๐Ÿ“ฌ Example Call (via Postman)

URL:

localhost:8080/api/users/57e268fc-da31-45b7-aad6-42021c9aea65/validate

Response:

{
    "id": "57e268fc-da31-45b7-aad6-42021c9aea65",
    "email": "atul@gmail.com",
    "password": "at@123",
    "firstName": null,
    "lastName": "kumar",
    "role": "USER",
    "createdAt": "2025-08-01T16:37:23.147215",
    "updatedAt": "2025-08-01T16:37:23.147215"
}

๐Ÿ’ก Final Thoughts

This integration made my app smarter, more scalable, and easier to maintain. If you're planning to build a real-world AI-powered microservice app with Spring Boot, this stack is powerful and production-ready:

โœ… Gemini for AI
โœ… Spring Cloud Config for centralized secrets
โœ… Spring Cloud Gateway for clean routing
โœ… Eureka for service discovery


๐Ÿ“š Resources

  • Spring Cloud Config Docs

  • Spring Cloud Gateway Docs

  • Spring Boot Web Flux Guide

  • Google Gemini API Overview


๐Ÿ“ž Contact

0
Subscribe to my newsletter

Read articles from Rudra Narayan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rudra Narayan
Rudra Narayan