OpenAI Integration with ChatGPT APIs and Spring AI in Spring Boot

Madhan Kumar
10 min readApr 10, 2024

--

Integrating OpenAI’s ChatGPT APIs and SpringAI with Spring Boot Java Framework

Objective :

This article explores the integration of OpenAI ChatGPT APIs and SpringAI within a Spring Boot application. Our goal is to create a Spring Boot application that can produce responses to a provided prompt using the OpenAI ChatGPT APIs and SpringAI.

ChatGPT ?

ChatGPT is a form of generative AI that enables users to input prompts and receive outputs in the form of human-like images, text, or videos, all created by artificial intelligence.

ChatGPT, a part of OpenAI, utilizes various models such as GPT-3.5, GPT-4, and others to generate responses based on given prompts.

What is Prompts in ChatGPT ?

ChatGPT prompts are instructions or queries that you enter into the artificial intelligence’s (AI) interface to get responses. A prompt consists of keywords and phrases meant to spark a reply.

For example, if you feed ChatGPT a question or instruction, it will respond as though in a conversation.

CHATGPT

Let’s explore the OpenAI ChatGTP API :

We’ll utilize the Create Chat Completion API (POST https://api.openai.com/v1/chat/completions) to generate responses based on a given prompt.

In that link, you can see the CURL API URL and the API input.

Here is the revised API request that I have asked the question, ‘What is Spring Boot?

curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "What is springboot?"
}
],
"temperature": 1
"max_tokens" :256
}'

Analyzing the fundamental request parameters for the API :

Model : This parameter specifies the model version that will receive requests. There are different model versions available, and for this task, we’ll use the “gpt-3.5-turbo” model, which is the most recent version accessible to the public.

Messages : Each message has two important parts: “role” and “content.” The “role” tells whether the message is from the user or the assistant. The “content” is the actual message text.

Temperature : By default, it’s set at 1, and it can range from 0 to 2. This controls how random the response is. Higher values make the response more random, while lower values make it more focused and predictable.

max_tokens : Normally, there’s no limit, but you can use this setting to decide the maximum number of words or symbols in the response. It helps manage really long responses and keeps costs under control.

If you attempt the request mentioned earlier in Postman without passing the OpenAI API Key as a bearer token, you’ll encounter an authentication failure. It’s crucial to include the OpenAI API Key as a bearer token to authenticate access to the OpenAI ChatGPT completion API.

Create OpenAI Key :

Log in to your ChatGPT account and create your OpenAI API key here

CREATE OPENAI KEY

OpenAI ChatGTP API Integration With Spring Boot :

Here is the project structure :

PROJECT STRUCTURE

Here are the utilized dependencies:

MAVEN DEPENDENCIES

Create ChatRequest, ChatResponse and Message Model Classes :

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRequest {

private String model;
private List<Message> messages;
private int n;
private double temperature;
}

---------------------------------------------------------------------------

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatResponse {

private List<Choice> choices;

@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Choice {
private int index;
private Message message;
}
}

---------------------------------------------------------------------------

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {

private String role;
private String content;

}

Add these configurations to application.properties file:

spring.application.name=openai-java
server.servlet.context-path=/openai

#OpenAI
openai.model=gpt-3.5-turbo
openai.api.key=REPLACE_YOUR_KEY
openai.api.url=https://api.openai.com/v1/chat/completions
openai.max-completions=1
openai.temperature=0

RestTemplate Configuration :

Establish a class named ChatGPTConfiguration within the configurations package

@Configuration
public class ChatGPTConfiguration {

@Value("${openai.api.key}")
private String apiKey;

/**
* Configures and returns a RestTemplate bean with an interceptor to add an Authorization header with the API key.
* @return A RestTemplate configured with an interceptor to add an Authorization header.
*/
@Bean
RestTemplate restTemplate() {

RestTemplate restTemplate = new RestTemplate();

restTemplate.getInterceptors().add((request, body, execution) -> {
request.getHeaders().add("Authorization", "Bearer " + apiKey);
return execution.execute(request, body);
});

return restTemplate;
}

}

The @Value(“${openai.api.key}”) annotation fetches information from the application’s properties file. Specifically, it retrieves the OpenAI API key from the file.

The RestTemplate bean defines a tool for making HTTP requests in Java. It configures an interceptor for the RestTemplate. Essentially, whenever the RestTemplate sends a request, the interceptor supplements it with an “Authorization” header. This header includes a bearer token fetched from the “apiKey” variable. Typically, this setup is used to authenticate requests to APIs that require a token for access.

API Controller :

Now, we can go ahead and make the REST controller. It will use the setup we’ve done with the RestTemplate to send requests to APIs and manage the responses we get back.

Create a class ChatAPIController under controllers package :

@RestController
@RequestMapping("/api/vi")
@Slf4j
public class ChatAPIController {

@Autowired
private RestTemplate restTemplate;

@Value("${openai.model}")
private String model;

@Value("${openai.max-completions}")
private int maxCompletions;

@Value("${openai.temperature}")
private double temperature;

@Value("${openai.api.url}")
private String apiUrl;

/**
* Handles chat requests by sending a prompt to a chat API and returning the response.
*
* @param prompt The prompt message provided by the user.
* @return The response generated by the chat API.
*/
@PostMapping("/chat")
public ChatResponse chat(@RequestParam("prompt") String prompt) {
/* Initialize variables */
ChatResponse chatResponse=null;
List<Message> ChatMessages = new ArrayList<>();
ChatRequestBuilder request = ChatRequest.builder();
try {
/* Add user prompt to chat messages */
ChatMessages.add(new Message("user", prompt));
/* Build chat request */
request
.model(model)
.messages(ChatMessages)
.n(maxCompletions)
.temperature(temperature);

/* Send chat request and obtain response */
chatResponse = restTemplate.postForObject(apiUrl, request.build(), ChatResponse.class);
}catch(Exception e) {
log.error("error : "+e.getMessage());
}
return chatResponse;
}

}

The coding part is completed. now, we will proceed to test the application.

API TESTING IN POSTMAN

Now, you can see that I am receiving a response from the OpenAI API for the question I asked.

What are the possibilities with the OpenAI ChatGPT Completion API ?

Here are some of the tasks you can accomplish using the OpenAI Completion API with models like ChatGPT :

Create Chatbots : Make chatbots that talk like humans. They can answer questions or chat with users naturally.

Help with Customer Support : Build systems to assist customers automatically, making support faster and more efficient.

Generate Content : Write articles, stories, or product descriptions automatically, saving time for content creators.

Translate Languages : Make tools that translate text between languages, helping people communicate globally.

Build Personal Assistants : Create virtual assistants to set reminders, schedule appointments, or answer questions.

Educational Tools : Assist students with homework or explanations, making learning more personalized.

Moderate Content : Automatically filter inappropriate content on websites or social media.

Market Research : Analyze large amounts of text data to find trends or insights for businesses.

These are some examples of what you can do with the OpenAI Completion API and models like ChatGPT. These models are useful in many areas like education, healthcare, customer service, and writing. Just remember, the quality of the text they produce can vary based on what you’re using them for and the information you give them.

Integrating Generative AI into Spring Boot Application with Spring AI :

Spring AI: Leveraging AiClient with Spring Boot Application

The goal of the Spring AI initiative is to simplify the process of creating applications with artificial intelligence capabilities, eliminating unnecessary complexity in Spring boot java.

Spring AI offers the following features :

  • Support for leading AI model providers including OpenAI, Microsoft, Amazon, Google, and Huggingface.
  • Spring AI works with different types of models like Chat and Text-to-Image. More types of models are being developed.
  • A universal API is provided across various AI providers for both Chat and Embedding models. You can choose between synchronous and stream API options. Additionally, accessing model-specific features is also facilitated.
  • Mapping of AI Model output to POJOs.
  • Support for all major Vector Database providers such as Azure Vector Search, Chroma, Milvus, Neo4j, PostgreSQL/PGVector, PineCone, Qdrant, Redis, and Weaviate.
  • Spring Boot Auto Configuration and Starters for AI Models and Vector Stores.

Note :

  • Spring-AI is very new and currently lacks a stable version. However, we anticipate releasing a stable version in the future.
  • Spring AI introduces the AiClient interface with implementations for OpenAI and Azure’s OpenAI.

Let’s start coding..

Dependencies needed in pom.xml :

To utilize Spring AI, add the following repository. Please note that it’s an experimental project, and only snapshot releases are accessible at this time.

SNAPSHOT REPOSITORY FOR OPENAI

To integrate OpenAI, you can add the following dependency :

MAVEN DEPENDENCY FOR OPENAI

You can also opt for Azure OpenAI instead of OpenAI by including the following dependency :

<dependency>
<groupId>org.springframework.experimental.ai</groupId>
<artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
<version>0.2.0-SNAPSHOT</version>
</dependency>

In this article, I have utilized OpenAI.

Add these configurations to application.properties file:


#SpringAI
spring.ai.openai.api-key=REPLACE_WITH_YOUR_API_KEY

Create AIServiceHelper within the services package :

@Service
@Slf4j
public class AIServiceHelper {

@Autowired
AiClient aiClient;

@Value("${spring.ai.openai.api-key}")
private String apiKey;

/**
* Generates a response to the provided question using the AI client.
*
* @param question The question asked by the user.
* @return The response generated by the AI client.
*/
public String chat(String question){
/* Initialize Variable */
PromptTemplate promptTemplate = null;
try {
/* Create a prompt template using the question */
promptTemplate = new PromptTemplate(question);
}catch(Exception e) {
log.error("error : "+e.getMessage());

}
/* Generate a response using the AI client and return the text of the generated response */
return this.aiClient.generate(promptTemplate.create()).getGeneration().getText();
}

/**
* Generates a document content for the specified topic using the AI client.
*
* @param topic The topic for which the document content needs to be generated.
* @return The generated document content as a string.
*/
public String generateDocument(String topic) {
/* Initialize variable */
PromptTemplate promptTemplate =null;
try {

/* Create a prompt template with place holders for the topic and document content instructions */
promptTemplate = new PromptTemplate("""
Generate document content for a {topic}.
It should be at least two pages long and include comprehensive information covering all aspects of the topic,
including background information, current trends or developments, relevant statistics or data, key concepts or
theories, potential challenges, and future outlook. The document should be well-structured with clear headings
and sub-headings, and it should provide an in-depth analysis that offers insights and engages the reader effectively.
""");

/* Replace the placeholder {topic} with the actual topic provided */
promptTemplate.add("topic", topic);
}catch(Exception e) {
log.error("error : "+e.getMessage());
}

/* Generate document content using the AI client and return the text of the generated content */
return this.aiClient.generate(promptTemplate.create()).getGeneration().getText();
}

Let’s analyze the code, step by step .

Injected Dependencies : The class uses the @Autowired annotation to bring in an instance of the AiClient interface. AiClient acts as a way to talk to the OpenAI service.

chat Method : This method is used to generate a response for a given question using an AI model. It first creates a prompt template using the provided question. Then, it utilizes the AI client to generate a response based on the prompt template. Finally, it returns the text of the generated response. Any errors that occur during prompt template creation are logged.

generateDocument Method : This method generates document content for a given topic using an AI model. It creates a prompt template with placeholders for the topic and document content instructions. Then, it replaces the placeholder {topic} with the actual topic provided. Finally, it utilizes the AI client to generate document content based on the prompt template and returns the text of the generated content. Any errors that occur during prompt template creation are logged.

Create SpringAIController within controllers package :

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

@Autowired
AIServiceHelper aiService;

/**
* Handles a question-answer request by providing a response generated by the AI service.
*
* @param question The question asked by the user.
* @return The response generated by the AI service.
*/
@GetMapping("/qa")
public String chat(@RequestParam String question) {
return aiService.chat(question);
}

/**
* Generates a document based on the provided topic using the AI service.
*
* @param topic The topic for which the document needs to be generated.
* @return A string representing the generated document.
*/
@GetMapping("/docuGenAI")
public String generateDocument(@RequestParam String topic) {
return aiService.generateDocument(topic);
}

The coding part is completed. now, we will proceed to test the application.

In the controller class, I’ve defined two endpoints,

API api/v1/qa : Handles a question-answer request by providing a response generated by the AI service.

API api/v1/docuGenAI : Generates a document content based on the provided topic using the AI service.

You can find the source code here 👇

https://github.com/iammadhankumar/openai-java

🌟 Encouragement & Interaction 🌟

Spring AI is fantastic. If you found this article informative and helpful, please consider expressing your appreciation by giving it a clap 👏. Don’t hesitate to share this article with your colleagues. Your support and sharing of knowledge within the developer community are greatly appreciated.

👉 Please share on social media
👉 Follow me on : Medium || LinkedIn

Thank You All

--

--

Madhan Kumar

Software Engineer (Java) | Blogger | Full Stack Developer | Python | AI Explorer