Unlock Your Python Backend Career: Build 30 Projects in 30 Days. Join now for just $54

PromptCraft: Mini AI Prompt Generator App Spring AI and Spring Boot

by Ayush Shrivastava

.

Updated Thu Aug 28 2025

.
PromptCraft: Mini AI Prompt Generator App Spring AI and Spring Boot

Mastering (11) (1).pngSpring Boot is a popular Java framework that makes it easy to build and run applications quickly. It provides ready-to-use features so you can focus on writing code instead of setting up everything from scratch. With Spring Boot, you can create web apps, APIs, and services in less time.

Spring AI is a new project that connects the power of artificial intelligence with Spring applications. It gives developers tools to work with AI models easily inside their Java projects. One of the most exciting uses of Spring AI is working with OpenAI, the company behind ChatGPT and other advanced AI models.

OpenAI provides smart models that can understand and generate text, answer questions, and even help write code. By combining Spring Boot, Spring AI, and OpenAI, developers can create powerful apps that think and respond like humans. This makes it possible to build AI-powered chatbots, content tools, or even creative assistants with very little setup.

Step 1: Create a New Spring Boot Project

  1. Go to

    https://start.spring.io/

  2. Fill details:

    • Project: Maven

    • Language: Java

    • Spring Boot: Latest version

    • Dependencies: Spring Web

image (51).png3. Click Generate Project and unzip it.

4. Open the project in IntelliJ IDEA / Eclipse.

Now you have a simple Spring Boot project ready. and create the project structure like this.

image (52).pngStep 2: Add Spring AI Dependency

Open your pom.xml and add

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

so updated pom.xml looks like this

<?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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.5</version>
        <relativePath/>
    </parent>

    <groupId>com.ayshriv</groupId>
    <artifactId>promptcraft</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>promptcraft</name>
    <description>PromptCraft – Mini AI Prompt Generator using Spring Boot + Spring AI (OpenAI only)</description>

    <properties>
        <java.version>21</java.version>
        <spring-ai.version>1.0.0</spring-ai.version>
    </properties>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
    </repositories>

    <dependencies>
        <!-- Spring Boot web stack -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- Lombok (optional) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
        </dependency>

        <!-- Testing -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <release>${java.version}</release>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Step 3: Get an OpenAI API Key

Step 1: Go to the OpenAI Website

Visit https://platform.openai.com in your browser.

Step 2: Sign In or Create an Account

Log in using your existing OpenAI account. If you don’t have one, sign up using your email, Google, or Microsoft account.


Step 3: Open the API Keys Section

Once logged in, click on your profile icon (top-right corner) and select "View API Keys" or go to https://platform.openai.com/account/api-keys directly.

Step 4: Generate a New API Key

Click on the "Create new secret key" button. A new key will be generated.


Step 5: Copy and Save Your Key

Copy the key and store it in a safe place (such as a password manager or .env file). You won’t be able to view it again after closing the popup.

Step 4: Add API Key to application.yml

server:
  port: 8080

spring:
  application:
    name: promptcraft
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini
          temperature: 0.7

Here we are using gpt-4o-mini.

Never share your API key in your code or upload it to public platforms like GitHub. If someone gets access to your key, they can misuse it, which could lead to unexpected charges or security issues. Instead, store your API key in a safe place, such as environment variables or a secure configuration file. For production applications, it’s recommended to use a secret manager or secure vault service to keep your keys and sensitive information protected.

Step 5: Write Your First AI Controller

package com.ayshriv.promptcraft.contrloller;

import com.ayshriv.promptcraft.core.TemplateStore;
import com.ayshriv.promptcraft.dto.CreateOrUpdateTemplateRequest;
import com.ayshriv.promptcraft.dto.GenerateRequest;
import com.ayshriv.promptcraft.dto.GenerateResponse;
import com.ayshriv.promptcraft.dto.PromptDefinition;
import com.ayshriv.promptcraft.service.PromptCraftService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class PromptController {
    private final TemplateStore store;
    private final PromptCraftService service;

    @GetMapping("/templates")
    public List<PromptDefinition> list() {
        return store.list();
    }

    @PostMapping("/templates")
    public ResponseEntity<PromptDefinition> upsert(@Valid @RequestBody CreateOrUpdateTemplateRequest req) {
        var def = new PromptDefinition(req.name(), req.description(), req.system(), req.userTemplate());
        store.upsert(def);
        return ResponseEntity.created(URI.create("/api/templates/" + def.name())).body(def);
    }

    @PostMapping("/generate")
    public GenerateResponse generate(@Valid @RequestBody GenerateRequest req) {
        String system = req.system();

        // If existing template name is found, use it; else treat req.template as raw template
        String userTemplate = store.get(req.template())
                .map(PromptDefinition::userTemplate)
                .orElse(req.template());

        if (system == null) {
            system = store.get(req.template()).map(PromptDefinition::system).orElse(null);
        }

        String content = service.generateFromTemplate(system, userTemplate, req.variables(), req.model());
        return new GenerateResponse(content);
    }
}

In This code is a Spring Boot REST controller that manages AI prompt templates and text generation.

  • /templates (GET) → Lists all saved templates.

  • /templates (POST) → Adds or updates a template with name, description, system, and user template.

  • /generate (POST) → Uses either a saved template or a raw template string to generate text with given variables and model.

Step 6: Create request and Response DTO’s

package com.ayshriv.promptcraft.dto;

public record PromptDefinition(
        String name,
        String description,
        String system,
        String userTemplate
) {}

In this code defines a record named PromptDefinition that simply holds details of a prompt template:

  • name → template name

  • description → short info about the template

  • system → system instructions

  • userTemplate → the user prompt pattern

package com.ayshriv.promptcraft.dto;

import jakarta.validation.constraints.NotBlank;

import java.util.Map;

public record GenerateRequest(
        @NotBlank String template,
        Map<String, Object> variables,
        String system,
        String model
) {}

In this code defines a record called GenerateRequest, which is used when asking the app to generate text. It contains:

  • template → the template name or raw text (must not be blank)

  • variables → key-value pairs to fill into the template

  • system → optional system instructions

  • model → which AI model to use

package com.ayshriv.promptcraft.dto;

public record GenerateResponse(String content) {}

In this code defines a record named GenerateResponse with one field:

  • content → the generated text output.

package com.ayshriv.promptcraft.dto;

import jakarta.validation.constraints.NotBlank;

public record CreateOrUpdateTemplateRequest(
        @NotBlank String name,
        String description,
        String system,
        @NotBlank String userTemplate
) {}

In this code defines a record called CreateOrUpdateTemplateRequest, used when creating or updating a template. It includes:

  • name → template name (must not be blank)

  • description → optional details about the template

  • system → optional system instructions

  • userTemplate → the actual template text (must not be blank)

Step 7: Create TemplateStore class of in-memory storage

package com.ayshriv.promptcraft.core;

import com.ayshriv.promptcraft.dto.PromptDefinition;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class TemplateStore {

    private final Map<String, PromptDefinition> templates = new ConcurrentHashMap<>();

    @PostConstruct
    void seed() {
        templates.put("twitter-hooks", new PromptDefinition(
                "twitter-hooks",
                "Generate 5 short, scroll-stopping hooks",
                "You are a concise, high-conversion copywriter.",
                """
                Generate 5 short hooks for a tweet thread about {topic}.
                Style: {style}. Keep each under 100 characters.
                Output as a numbered list only.
                """
        ));

        templates.put("summarize", new PromptDefinition(
                "summarize",
                "TL;DR in bullet points",
                "You are an expert technical summarizer.",
                """
                Summarize the following content into 5 crisp bullets for {audience}:
                ---
                {content}
                ---
                """
        ));

        templates.put("rewrite-tone", new PromptDefinition(
                "rewrite-tone",
                "Rewrite text in a tone and length",
                "You are a helpful rewriting assistant.",
                """
                Rewrite the text in a {tone} tone and keep it around {words} words.
                Text:
                {text}
                """
        ));
    }

    public List<PromptDefinition> list() {
        return new ArrayList<>(templates.values());
    }

    public Optional<PromptDefinition> get(String name) {
        return Optional.ofNullable(templates.get(name));
    }

    public PromptDefinition upsert(PromptDefinition def) {
        templates.put(def.name(), def);
        return def;
    }
}

TemplateStore is like a small in-memory database for templates, so the app can quickly fetch or update them when generating AI responses.

Step 8: Create PromptCraftServicefor generating prompt with AI.

package com.ayshriv.promptcraft.service;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.openai.OpenAiChatOptions;

import java.util.Map;

@Service
public class PromptCraftService {

    private final ChatClient chat;

    public PromptCraftService(ChatClient.Builder chatBuilder) {
        this.chat = chatBuilder.build();
    }


    public String renderTemplate(String rawTemplate, Map<String, Object> vars) {
        PromptTemplate t = new PromptTemplate(rawTemplate);
        return t.render(vars == null ? Map.of() : vars);
    }

    public String generate(String system, String user, String model) {
        if (!StringUtils.hasText(user)) {
            throw new IllegalArgumentException("User message must not be empty");
        }

        var prompt = chat.prompt();

        if (StringUtils.hasText(system)) {
            prompt = prompt.system(system);
        }

        prompt = prompt.user(user);


        if (StringUtils.hasText(model)) {
            return prompt
                    .options(OpenAiChatOptions.builder().model(model).build())
                    .call()
                    .content();
        }

        return prompt.call().content();
    }


    public String generateFromTemplate(String system,
                                       String userTemplate,
                                       Map<String, Object> vars,
                                       String model) {
        String user = renderTemplate(userTemplate, vars);
        return generate(system, user, model);
    }
}

The PromptCraftService class is the core engine that connects with the AI model and generates responses. It uses Spring AI’s ChatClient to send prompts to an AI service like OpenAI. First, it can take a raw template with placeholders and replace them with actual values using the renderTemplate method, producing a user-ready prompt. Then, through the generate method, it builds the final AI request by combining optional system instructions, the user’s message, and an optional model name, before calling the AI and returning the generated content. Finally, the generateFromTemplate method ties everything together by rendering a user template with variables and then sending it along with system instructions to the AI. In short, this service is responsible for turning templates into complete prompts, sending them to the AI, and returning useful responses.

You can download the source code from here:

https://github.com/ayushstwt/PromptCraft.git

Step 9: Testing EndPoints

Create Template

curl --location 'http://localhost:8080/api/templates' \
--header 'Content-Type: application/json' \
--data '{
        "name": "motivational-quote",
        "description": "Generate motivational quotes about coding",
        "system": "You are a helpful assistant that inspires developers.",
        "userTemplate": "Write a motivational quote about {{topic}}."
      }'

image (53).pngGenerate Prompt

curl --location 'http://localhost:8080/api/generate' \
--header 'Content-Type: application/json' \
--data '{
        "template": "motivational-quote",
        "variables": {
          "topic": "Java programming"
        },
        "model": "gpt-4o-mini"
      }'

image (55).pngConclusion

PromptCraft is a lightweight AI-powered prompt generator built with Spring Boot and Spring AI. It allows users to create, store, and reuse templates, making AI interactions more structured and efficient. With its simple REST APIs, developers can quickly generate responses, test different models, and integrate prompt management into their applications.

Whenever you're ready

There are 4 ways we can help you become a great backend engineer:

The MB Platform

Join 1000+ backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.

The MB Academy

The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.

Join Backend Weekly

If you like post like this, you will absolutely enjoy our exclusive weekly newsletter, Sharing exclusive backend engineering resources to help you become a great Backend Engineer.

Get Backend Jobs

Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board

Backend Tips, Every week

Backend Tips, Every week