Chaturmind
LearnDSASystem DesignBlogPremium
Sign inGet started
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML

Company

  • Blog
  • Premium
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Prompt Engineering & LLM APIs

Prompt Engineering

  • Prompt Engineering Basics
  • Chain-of-Thought Prompting

LLM APIs in Java

  • OpenAI API Integration
  • RAG — Retrieval-Augmented Generation
Chaturmind
← Prompt Engineering & LLM APIs

Prompt Engineering

  • Prompt Engineering Basics
  • Chain-of-Thought Prompting

LLM APIs in Java

  • OpenAI API Integration
  • RAG — Retrieval-Augmented Generation
HomeLearnAI & MLPrompt EngineeringAI APIs
✓ FreeIntermediate· 13 min read

OpenAI API Integration

Integrate the OpenAI API in Java/Spring Boot: chat completions, streaming, function calling, and embeddings.

Published May 12, 2025


OpenAI API Integration

The OpenAI API gives programmatic access to GPT-4 and other models. Integrating it into a Spring Boot application enables AI-powered features like summarization, extraction, Q&A, and code generation.

Setup

<!-- pom.xml -->
<dependency>
    <groupId>com.theokanning.openai-gpt3-java</groupId>
    <artifactId>service</artifactId>
    <version>0.18.2</version>
</dependency>

<!-- Or use Spring AI -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
# application.yml
openai:
  api-key: ${OPENAI_API_KEY}
  model: gpt-4o
  max-tokens: 1000
  temperature: 0.7

Basic Chat Completion (Spring AI)

@Service
@RequiredArgsConstructor
public class AiService {

    private final ChatClient chatClient;

    public String summarize(String text) {
        return chatClient.prompt()
            .system("You are a technical writer. Summarize text concisely.")
            .user("Summarize this in 3 bullet points:\n" + text)
            .call()
            .content();
    }

    public String generateCode(String description, String language) {
        return chatClient.prompt()
            .system("You are an expert " + language + " developer. Return ONLY code.")
            .user(description)
            .call()
            .content();
    }
}

Streaming Response

public Flux<String> streamResponse(String userMessage) {
    return chatClient.prompt()
        .user(userMessage)
        .stream()
        .content(); // Flux<String> — each element is a token chunk
}

// In controller:
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> stream(@RequestParam String message) {
    return aiService.streamResponse(message)
        .map(chunk -> ServerSentEvent.builder(chunk).build());
}

Function Calling (Tool Use)

Allow the model to call your Java methods:

@Bean
public List<FunctionCallback> tools() {
    return List.of(
        FunctionCallbackWrapper.builder(new GetWeatherFunction())
            .withName("getCurrentWeather")
            .withDescription("Get the current weather for a city")
            .withResponseConverter(r -> r.toString())
            .build()
    );
}

record WeatherRequest(String city) {}
record WeatherResponse(String city, double temp, String condition) {}

@Component
public class GetWeatherFunction
        implements Function<WeatherRequest, WeatherResponse> {
    @Override
    public WeatherResponse apply(WeatherRequest req) {
        // Call actual weather API
        return new WeatherResponse(req.city(), 22.5, "Sunny");
    }
}

// Usage - model decides when to call the tool
String response = chatClient.prompt()
    .user("What's the weather in Tokyo?")
    .functions("getCurrentWeather")
    .call()
    .content();

Embeddings for Semantic Search

@Service
@RequiredArgsConstructor
public class EmbeddingService {

    private final EmbeddingClient embeddingClient;

    public float[] embed(String text) {
        EmbeddingResponse response = embeddingClient.embedForResponse(List.of(text));
        return response.getResults().get(0).getOutput();
    }

    public double cosineSimilarity(float[] a, float[] b) {
        double dot = 0, normA = 0, normB = 0;
        for (int i = 0; i < a.length; i++) {
            dot  += a[i] * b[i];
            normA += a[i] * a[i];
            normB += b[i] * b[i];
        }
        return dot / (Math.sqrt(normA) * Math.sqrt(normB));
    }
}

Error Handling

try {
    String result = chatClient.prompt().user(message).call().content();
} catch (OpenAiHttpException e) {
    if (e.statusCode == 429) {
        // Rate limited — retry with exponential backoff
    } else if (e.statusCode == 400) {
        // Invalid request — check prompt length, content policy
    }
}

Interview Tips

  1. Always store API keys in environment variables — never hardcode in source.
  2. Implement rate limiting on your side — the OpenAI API has token and request limits.
  3. Use streaming for long responses — users can see text appearing rather than waiting.

Previous

Chain-of-Thought Prompting

Next

RAG — Retrieval-Augmented Generation

AI Tutor

Lesson: OpenAI API Integration

Quick actions

AI responses can be inaccurate. Verify critical information.