Hi everyone, Igor Fraga here! Welcome to the first post in my Spring AI series! In this article, I’ll explain what Spring AI is, what it’s used for, and walk you through the basics of the spring-ai-intro repository. You’ll see how to connect your Java applications with OpenAI’s ChatGPT using Spring AI — with simple examples, code, and explanations. Let’s get started!


What Is Spring AI?

Spring AI is a library from the Spring ecosystem that makes it easy to add Artificial Intelligence (AI) features to your Java and Spring Boot applications. With Spring AI, you can use popular AI LLM APIs (like OpenAI, Azure, Mistral, Amazon Bedrock, local Ollama LLMs and more to come) in your microservices, websites, or backend tools using Java code. It helps a lot with the hard work of connecting, sending prompts, and reading responses from AI models.


About the spring-ai-intro Repository

This repository is a step-by-step practical guide to integrating Spring AI with OpenAI’s ChatGPT. It’s designed for people who want to learn by doing, starting simple and growing to more advanced use cases.

Main Features:

  • Uses Java 21+ and Spring Boot
  • Shows how to call OpenAI’s API using Spring AI
  • Demonstrates several prompt engineering techniques (check out the JUnit tests)
  • Provides ready endpoints you can test right away

How Does It Work?

  1. You send a request (for example, a question) to the endpoint.
  2. The application uses Spring AI’s classes to send your prompt to OpenAI’s API.
  3. The response from OpenAI is returned to you—either as plain text or structured data.

You can ask questions by sending a POST request to /ask. Here’s an example from the code:

@PostMapping("/ask")
public Answer askQuestion(@RequestBody Question question) {
    return openAIService.getAnswer(question);
}

The OpenAIServiceImpl class handles the real work. Look at this method:

@Override
public String getAnswer(String question) {
    PromptTemplate promptTemplate = new PromptTemplate(question);
    Prompt prompt = promptTemplate.create();

    ChatResponse response = chatModel.call(prompt);
    return response.getResult().getOutput().getText();
}
  • It creates a prompt from your question.
  • Sends it to OpenAI using the Spring AI chatModel.
  • Gets the response and returns it.

This is a very simplistic approach and we will dive deeper on more elaborated prompts below.


Getting the Capital City

The repository also has endpoints where you ask for the capital of a country or state. For example:

@PostMapping("/capital")
public Answer getCapital(@RequestBody GetCapitalRequest stateOrCountry) {
    return openAIService.getCapital(stateOrCountry);
}

The service uses a prompt template. Instead of hardcoding the prompt, it loads it from a file and fills in the blanks:

PromptTemplate promptTemplate = new PromptTemplate(getCapitalPrompt);
Prompt prompt = promptTemplate.create(Map.of("stateOrCountry", capitalRequest.stateOrCountry()));
ChatResponse response = chatModel.call(prompt);
return new Answer(response.getResult().getOutput().getText());
  • getCapitalPrompt loads the template file.
  • The Map.of(...) call provides values for the placeholders.
  • promptTemplate.create(...) replaces {stateOrCountry} with the actual values from the request.

This makes it easy to reuse and change prompts without changing code.

The getCapitalPrompt is a file that holds the prompt with the variables. You need to map the real values to these variables when you create your prompt from prompt template, as seen with the stateOrCountry variable. The value of getCapitalPrompt is injected as a String as showed below:

@Value("classpath:templates/get-capital-prompt.st")
private Resource getCapitalPrompt;

@Value("classpath:templates/get-capital-json-response-prompt.st")
private Resource getCapitalJSONPrompt;

@Value("classpath:templates/get-capital-with-info-prompt.st")
private Resource getCapitalWithInfoPrompt;

Each @Value annotation points to a different prompt template file in the templates directory. This allows you to manage and tweak your prompts independently of the application code.


Prompts used in this project

Here are the prompts you might find in the .st files in the templates directory:

get-capital-prompt.st

What is the capital of {stateOrCountry}?

get-capital-json-response-prompt.st

What is the capital of {stateOrCountry}? Please answer only in the following JSON format: {format}

get-capital-with-info-prompt.st

Give me the capital of {stateOrCountry} and provide a short fact about it.

Notice the {stateOrCountry} and {format} placeholders—these are variables that will be dynamically replaced with runtime values.


Getting Structured JSON Data

Spring AI makes it simple to ask OpenAI for structured answers (like JSON), not just plain text. Here’s a simplified example:

BeanOutputConverter<GetCapitalResponse> converter = new BeanOutputConverter<>(GetCapitalResponse.class); // defines the JSON format we want
String format = converter.getFormat();

PromptTemplate promptTemplate = new PromptTemplate(getCapitalJSONPrompt);
Prompt prompt = promptTemplate.create(Map.of(
    "stateOrCountry", capitalRequest.stateOrCountry(),
    "format", format
));

ChatResponse response = chatModel.call(prompt);
return converter.convert(response.getResult().getOutput().getText());
  • The BeanOutputConverter helps define the expected JSON structure.
  • The prompt tells OpenAI to answer in this format.
  • The code converts OpenAI’s JSON response directly to a Java object.

And you also have an endpoint to test this example as showed below:

@PostMapping("/capitalJSON")
public GetCapitalResponse getCapitalJSON(@RequestBody GetCapitalRequest stateOrCountry) {
    return openAIService.getCapitalJSON(stateOrCountry);
}

Just give it a try, passing a JSON format and see what you get on the output.


How To Run The Example

  1. Clone the repo: git clone https://github.com/Intercont/spring-ai-intro.git
  2. Add your OpenAI API key by setting the environment variable: export OPENAI_API_KEY=YOUR_OPENAI_API_KEY
  3. Build: mvn clean package
  4. Run: mvn spring-boot:run
  5. Try the endpoints! You can use curl, Postman, or any HTTP client.

Conclusion

Spring AI makes it much easier to use powerful AI models like OpenAI ChatGPT in your Java projects. The spring-ai-intro repository is a great place to start if you want to see real, working code and learn how to build your own AI-powered features.

In the next post, I’ll introduce RAG (Retrieval-Augmented Generation) concept and present the implementation of a simple vector database, interacting with OpenAI on the spring-ai-rag repository. Subscribe at igorfragadev.com to follow the series!


Repository: Intercont/spring-ai-intro