Spring Boot Gemini AI Integration Guide: REST API, GCS Upload, and application.yml Explained

Thumbnail for Spring Boot Gemini AI Integration Guide showing REST API flow, GCS upload, and application.yml configuration

Spring Boot + Gemini Vertex AI: Smart Configuration and File-Aware Code Flow

In this section, we walk through the complete backend architecture that connects Spring Boot 2.6 with Gemini Vertex AI using REST. This design uses file-aware logic to decide when to embed a file or upload it to Google Cloud Storage (GCS), all managed by configuration through application.yml.

Centralized Configuration in application.yml

The application uses a single YAML configuration file to manage:

  • model-endpoint: REST API URL to call Gemini
  • gcs-upload-url: Template for uploading files to GCS
  • bucket-name: Target bucket for large file uploads
  • access-token: Token injected via environment or Google service credentials
  • instruction-text: Default system instruction for Gemini agent behavior
  • Proxy setup: Includes host, port, bypass list, and protocol

These are bound into Spring Boot using GeminiConfig.java and ProxyConfig.java via @ConfigurationProperties.

Configuration Binding Classes

  • GeminiConfig: Binds model ID, GCS URLs, tokens, and templates
  • ProxyConfig: Reads proxy settings and applies them as system properties
  • JavaExecutorConfig: Optional class for executing compiled Java code (used in advanced scenarios)

Unified Endpoint in DocumentController

The entrypoint for all Gemini operations is:

POST /bancsai/api/doc/processJson

This endpoint is mapped in the controller and calls GeminiService.processJson():

@PostMapping(value = "/processJson", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> processJsonRequest(@RequestBody Map<String, Object> requestJsonMap) {
    JsonObject requestJson = new Gson().toJsonTree(requestJsonMap).getAsJsonObject();
    GeminiFunctionCall result = geminiService.processJson(requestJson);
    ...
}

GeminiService.java – Core Business Logic

The class GeminiService handles all Gemini-related operations. The core method processJson() does the following:

  • Extracts prompt and file information from the incoming JSON request
  • If a file is present, determines its size using isInlineFile()
  • For small files: extracts base64 and embeds as inlineData
  • For large files: decodes, uploads to GCS via uploadFileBytesToGCS(), and adds a fileUri
  • Prepares a Gemini-compliant payload including generation config
  • Calls Gemini using the method callGeminiApi()

Deciding File Type Using isInlineFile()

This utility method decides whether to embed or upload based on the configured threshold (7MB):

private static boolean isInlineFile(String text, Charset charset, long thresholdBytes) {
    byte[] bytes = text.getBytes(charset);
    return bytes.length < thresholdBytes;
}

Uploading Large Files to GCS

The method uploadFileBytesToGCS() takes decoded bytes, builds an authenticated request using the GCS upload URL template, and returns a gs:// file URI:

private String uploadFileBytesToGCS(String fileName, String contentType, byte[] fileBytes) {
    String uploadUrl = config.getGcsUploadUrl(fileName);
    ...
    return "gs://" + config.getBucketName() + "/" + fileName;
}

This file URI is then included in the Gemini request payload as file_data.

Calling the Gemini REST API

The callGeminiApi() method sends the prepared JSON request to the Gemini endpoint using HttpURLConnection. It sets headers like:

  • Authorization: Bearer <accessToken>
  • Content-Type: application/json

All payloads and responses are logged using HttpLogHelper.logRequest() and logResponse().

Token Handling and Proxy Routing

Google OAuth2 tokens are generated using:

GoogleCredentials.fromStream(...).createScoped(SCOPES).refreshAccessToken()

Proxy setup is read from application.yml and set globally at runtime by ProxyConfig. This enables Gemini and GCS calls to work in corporate networks.

Request Logging and Filter Middleware

To support full request/response logging, the following classes are used:

  • CachedBodyHttpServletRequest
  • CachedBodyHttpServletResponse
  • RequestResponseLoggingFilter

These enable request re-reading without disrupting Spring's input stream, so full audit logs can be captured.

Summary of Backend Workflow

  • Incoming prompt (and file, if any) is sent to /processJson
  • GeminiService handles decision making (embed vs upload)
  • Configuration is cleanly externalized in application.yml
  • All calls to external APIs (Gemini, GCS) are logged and secured with proper OAuth2
  • Proxy and request logging is fully integrated

Contributor: Team CodeNib — Spring Boot Gemini Integration Series, Page 2

Post a Comment

0 Comments