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
- Log in to Google Cloud Console
- Go to console.cloud.google.com
- Select or create your project
- Enable Vertex AI API
- Navigate to APIs & Services > Library
- Search for "Vertex AI API"
- Click Enable
- 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
- Assign Required Roles
- Add these roles:
- Vertex AI User (essential)
- Service Account User (recommended)
- Click Continue then Done
- Add these roles:
- 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)
- Place your service account JSON in
src/main/resources
- 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:
- Adding Rate Limiting
- Protect your API from abuse with Spring Security
- Implementing Caching
- Cache common queries to save costs
- Building a Frontend
- Create a simple React/Vue.js interface
- 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!