CODE WITH SIBIN

Solving Real Problems with Real Code


Integrating Vertex AI Gemini with Spring Boot

Introduction

Hey there, fellow developer! 👋 If you're looking to harness the power of Google's Vertex AI Gemini in your Spring Boot applications, you've come to the right place. In this hands-on guide, I'll walk you through every step - from setting up your project to making your first AI-powered API call. Let's build something awesome together!

Prerequisites Checklist

Before we dive in, make sure you have:

  • ☑️ JDK 17+ installed
  • ☑️ Maven 3.6+ ready to go
  • ☑️ A Google Cloud account (with billing enabled)
  • ☑️ Vertex AI API enabled in your GCP project
  • ☑️ A service account with Vertex AI User permissions

Step 1: Project Setup

The Complete pom.xml

Here's the complete Maven configuration I've personally used and tested:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <!-- Spring Boot Parent for dependency management -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.4</version>
        <relativePath/>
    </parent>

    <groupId>com.yourcompany</groupId>
    <artifactId>gemini-spring-demo</artifactId>
    <version>1.0.0</version>
    <name>Gemini Spring Demo</name>
    <description>Spring Boot integration with Vertex AI Gemini</description>

    <properties>
        <java.version>17</java.version>
        <!-- Using the latest milestone release as of June 2024 -->
        <spring-ai.version>1.0.0-M7</spring-ai.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Web Starter for REST API -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI Vertex Gemini Integration -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-vertex-ai-gemini</artifactId>
        </dependency>

        <!-- Testing -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- Spring AI Bill of Materials -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Step 2: Configuration

Getting Your Google Cloud Service Account JSON

  1. Log in to Google Cloud Console
  2. Enable Vertex AI API
    • Navigate to APIs & Services > Library
    • Search for "Vertex AI API"
    • Click Enable
  3. Create a Service Account
    • Go to IAM & Admin > Service Accounts
    • Click + Create Service Account
    • Enter a name like "vertex-ai-access"
    • Click Create and Continue
  4. Assign Required Roles
    • Add these roles:
      • Vertex AI User (essential)
      • Service Account User (recommended)
    • Click Continue then Done
  5. Generate JSON Key
    • Find your new service account in the list
    • Click the three dots ⋮ > Manage keys
    • Click Add Key > Create new key
    • Select JSON format
    • Click Create (this downloads the key file)

application.properties

# =============================================
# Vertex AI Gemini Configuration
# =============================================

# Required Settings
spring.ai.vertex.ai.gemini.project-id=your-gcp-project-id
spring.ai.vertex.ai.gemini.location=us-central1

# Model Configuration
spring.ai.vertex.ai.gemini.chat.model=gemini-pro
spring.ai.vertex.ai.gemini.chat.options.temperature=0.4
spring.ai.vertex.ai.gemini.chat.options.top-k=20
spring.ai.vertex.ai.gemini.chat.options.top-p=0.9

# Optional Performance Tuning
spring.ai.vertex.ai.gemini.chat.options.max-output-tokens=2048

Authentication Setup

I recommend these two approaches:

Option 1: Environment Variable (Production)

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your-service-account.json"

Option 2: Classpath Resource (Development)

  1. Place your service account JSON in src/main/resources
  2. Add to application.properties:
spring.cloud.gcp.credentials.location=classpath:service-account.json

Pro Tip: Always add your service account JSON to .gitignore!

Step 3: Building the AI Service Layer

Let's create a proper service layer instead of putting everything in the controller:

GeminiService.java

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class GeminiService {
    
    private final ChatClient chatClient;

    public GeminiService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    public String generateContent(String prompt) {
        return chatClient.call(prompt);
    }

    public ChatResponse generateDetailedResponse(String prompt) {
        return chatClient.call(new Prompt(prompt));
    }

    public String generateTechnicalAnswer(String question) {
        SystemPromptTemplate systemPrompt = new SystemPromptTemplate("""
            You are a senior software engineer with 15 years of experience.
            Answer technical questions about {topic} clearly and concisely.
            Provide code examples when appropriate.
            Current date: {date}
            """);
        
        Prompt engineeredPrompt = systemPrompt.create(
            Map.of("topic", "Spring Boot", 
                  "date", java.time.LocalDate.now().toString())
        );
        
        return chatClient.call(engineeredPrompt).getResult().getOutput().getContent();
    }
}

Step 4: The REST Controller

AiController.java

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/ai")
public class AiController {

    private final GeminiService geminiService;

    public AiController(GeminiService geminiService) {
        this.geminiService = geminiService;
    }

    @GetMapping("/simple")
    public ResponseEntity<String> simplePrompt(@RequestParam String message) {
        return ResponseEntity.ok(geminiService.generateContent(message));
    }

    @PostMapping("/technical")
    public ResponseEntity<String> technicalQuestion(@RequestBody String question) {
        return ResponseEntity.ok(geminiService.generateTechnicalAnswer(question));
    }

    @GetMapping("/health")
    public ResponseEntity<String> healthCheck() {
        return ResponseEntity.ok("AI service is running!");
    }
}

Step 5: Testing Like a Pro

Postman Collection Tests

1. Simple GET Request

GET http://localhost:8080/api/v1/ai/simple?message=Tell%20me%20about%20Spring%20Boot%203

2. Technical Question POST Request

POST http://localhost:8080/api/v1/ai/technical
Content-Type: text/plain

"How do I implement JWT authentication in Spring Boot?"

Expected Responses

Successful Response (200 OK)

{
    "response": "Spring Boot 3 is the latest generation...",
    "timestamp": "2024-06-15T14:30:00Z"
}

Error Response (429 Too Many Requests)

{
    "error": "Too many requests",
    "message": "Rate limit exceeded. Please try again later.",
    "status": 429
}

Troubleshooting Common Issues

Problem: Getting 401 Unauthorized errors
✅ Fix: Double-check your service account has the "Vertex AI User" role
✅ Verify your JSON key path is correct

Problem: Slow response times
✅ Try moving your GCP resources to the same region as your client
✅ Reduce the max-output-tokens in your configuration

Problem: Responses seem generic
✅ Experiment with different temperature values (0.3-0.7 works well for technical answers)
✅ Use the prompt engineering techniques shown above

Where to Go From Here

Now that you have the basics working, consider:

  1. Adding Rate Limiting
    • Protect your API from abuse with Spring Security
  2. Implementing Caching
    • Cache common queries to save costs
  3. Building a Frontend
    • Create a simple React/Vue.js interface
  4. Exploring Advanced Features
    • Multi-turn conversations
    • Image processing (when supported)

Final Thoughts

I remember when I first integrated AI into a Spring Boot app - it felt like magic! But as you've seen, with the right tools and a bit of configuration, it's completely achievable. The Spring AI project is evolving quickly, so keep an eye on their GitHub for updates.

If you run into any snags while implementing this, don't hesitate to reach out. Happy coding, and may your AI integrations be smooth and your APIs responsive!

Leave a Reply

Your email address will not be published. Required fields are marked *