Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, July 19, 2026

An Open Letter to Java ...

I recently watched The Java Story, a documentary chronicling the journey of one of the world's most influential programming languages. It wasn't just a story about technology. It was a story about the people who built it, the community that shaped it, and the millions of developers whose careers were intertwined with it.

It also made me realise something.

I've never actually stopped to thank Java.

So... 

Dear Java,

We've been working together for more than two decades.

You've been with me through university assignments, late-night debugging sessions, production incidents, ambitious side projects, and countless enterprise transformations. You've taken me from writing desktop applications and web services to architecting cloud-native platforms that process millions of transactions.

Technology has changed dramatically over those years.

We've gone from monoliths to microservices. From physical servers to containers and Kubernetes. From XML configuration to convention over configuration. From synchronous request-response to event-driven architectures. And now, we're entering an era where AI is becoming part of every developer's toolkit.

Through it all, you've quietly evolved.

I've watched you introduce generics, lambdas, streams, modules, records, text blocks, virtual threads, pattern matching, and now AI-first developer frameworks like Spring AI. Every few years someone would declare you obsolete. Every few years you responded the same way, not with marketing, but with engineering.

You simply became better.

As developers, we're often distracted by the newest language or framework. Innovation is exciting, and experimentation is healthy. But I've come to appreciate a different quality.

Longevity.

The systems we build aren't measured by how fashionable the technology stack was on launch day. They're measured by whether they continue delivering value years later. Java understood that long before many of us did.

Looking back, you've given me much more than a programming language.

You've introduced me to extraordinary colleagues, mentors, and lifelong friends. You've challenged me to become a better engineer. You've provided a career that has taken me across industries, organisations, and countries. You've allowed me to spend over two decades doing something I genuinely enjoy: building software that solves real problems.

Today my role is Solution Architecture. I spend more time discussing business capability, integration patterns, distributed systems, and operating models than writing production code.

But I still build.

I still prototype.

I still experiment.

And more often than not, I still reach for Java.

Not because it's the only tool worth using, but because it's a tool I've learned to trust.

Watching The Java Story reminded me that software isn't only about code. It's about communities, craftsmanship, and the cumulative work of millions of people who quietly make the world run.

So thank you.

Thank you for adapting without abandoning your principles.

Thank you for proving that stability and innovation are not mutually exclusive.

And thank you for making the last twenty-plus years an incredible journey.

Here's to whatever we build next.


I'd love to hear from others.

What was your first Java project, and what keeps you coming back to it today? Or, if you've moved on, what lessons from Java have stayed with you throughout your career?

Friday, August 01, 2025

Building a Modern React Frontend for Movie Vibes: A Journey Through CSS Frameworks, AI Timeouts, and Real-World Development

How it started ...

A couple of days ago, I shared the creation of Movie Vibes, an AI-powered Spring Boot application that analyzes movie "vibes" using Spring AI and Ollama. The backend was working beautifully, but it was time to build a proper user interface. What started as a simple "add React + Tailwind" task turned into an educational journey through modern frontend development challenges, framework limitations, and the beauty of getting back to fundamentals.


How it's going ... 

The Original Plan: React + Tailwind CSS

The plan seemed straightforward:

  • ✅ React 18 + TypeScript for the frontend
  • ✅ Tailwind CSS for rapid styling
  • ✅ Modern, responsive design
  • ✅ Quick development cycle

How hard could it be? Famous last words.


The Tailwind CSS Nightmare

The Promise vs. Reality

Tailwind CSS markets itself as a "utility-first CSS framework" that accelerates development. In theory, you get: 

  • Rapid prototyping with utility classes
  • Consistent design tokens
  • Smaller CSS bundles
  • No context switching between CSS and HTML

In practice, with Create React App and Tailwind v4, we got:

  • ๐Ÿšซ Build failures due to PostCSS plugin incompatibilities
  • ๐Ÿšซ Cryptic error messages about plugin configurations
  • ๐Ÿšซ Hours of debugging CRACO configurations
  • ๐Ÿšซ Version conflicts between Tailwind v4 and CRA's PostCSS setup

The Technical Issues

The error that started it all:
Error: Loading PostCSS Plugin failed: tailwindcss directly as a PostCSS plugin has moved to @tailwindcss/postcss

We tried multiple solutions:

  1. CRACO configuration - Failed with plugin conflicts
  2. Downgrading to Tailwind v3 - Still had PostCSS issues
  3. Custom PostCSS config - Broke Create React App's build process
  4. Ejecting CRA - Nuclear option, but defeats the purpose

The Breaking Point

After spending more time debugging Tailwind than actually building features, I made a decision: dump Tailwind entirely. Sometimes the best solution is the simplest one.

The Pure CSS Renaissance

Going Back to Fundamentals

Instead of fighting with framework abstractions, we built a custom CSS design system that:

  • Compiles instantly - No build step complications
  • Full control - Every pixel exactly where we want it
  • No dependencies - Zero external CSS frameworks
  • Better performance - Only the CSS we actually use
  • Maintainable - Clear, semantic class names

The CSS Architecture


          /* Semantic, maintainable class names */
          .movie-card {
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
            transition: box-shadow 0.3s ease;
          }

          .movie-card:hover {
          	box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
          }

          /* Responsive design without utility class bloat */
          @media (max-width: 768px) 
          {
            .movie-card {
              /* Mobile-specific styles */
            }
          }
          

Compare this to Tailwind's approach:


<!-- Tailwind: Utility class soup -->
<div className="bg-white rounded-xl shadow-lg p-6 hover:shadow-2xl 
            	transition-shadow duration-300 md:p-8 lg:p-10">
        
Our approach is more readable, maintainable, and debuggable.

The AI Timeout Challenge

The Problem

Once the UI was working, we discovered a new issue: AI operations take time. Our local Ollama model could take 30-60 seconds to analyze a movie and generate recommendations. The frontend was timing out before the AI finished processing.

The Solution

We implemented a comprehensive timeout strategy:

// 2-minute timeout for AI operations
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 120000);

// User-friendly loading messages
<p className="loading-text">
  Please wait, this process can take 30-60 seconds while our AI agent 
  analyzes the movie and generates recommendations ✨
</p>
Key improvements:
  • ⏱️ Extended timeout to 2 minutes for AI operations
  • ๐ŸŽฏ Clear user expectations with realistic time estimates
  • ๐Ÿ”„ Graceful error handling with timeout-specific messages
  • ๐Ÿ“ฑ Loading states that don't feel broken

The Poster Image Quest

Backend Enhancement

The original backend only returned movie titles in recommendations. Users expect to see poster images! We enhanced the system to:

  1. Fetch complete metadata for the main movie ✅
  2. Parse AI-generated recommendations to extract movie titles
  3. Query OMDb API for each recommendation's metadata
  4. Include poster URLs in the API response

Performance Optimization

To balance richness with performance:

  • ๐ŸŽฏ Limit to 5 recommendations to avoid excessive API calls
  • ๐Ÿ›ก️ Fallback handling when movie metadata isn't found
  • ๐Ÿ“Š Detailed logging for debugging and monitoring

The Final Architecture

Frontend Stack

  • React 18 + TypeScript - Modern, type-safe development
  • Pure CSS - Custom utility system, no framework dependencies
  • Responsive Design - Mobile-first approach
  • Error Boundaries - Graceful handling of failures

Backend Enhancements

  • Spring Boot 3.x - Robust, production-ready API
  • Spring AI + Ollama - Local LLM for movie analysis
  • OMDb API Integration - Rich movie metadata
  • Intelligent Caching - Future enhancement opportunity

API Evolution


          {
            "movie": {
              "title": "Mission: Impossible",
              "poster": "https://...",
              "year": "1996",
              "imdbRating": "7.2",
              "plot": "Full plot description..."
            },
            "vibeAnalysis": "An exhilarating action-adventure...",
            "recommendations": [
              {
                "title": "The Bourne Identity",
                "poster": "https://...",
                "year": "2002",
                "imdbRating": "7.9"
              }
            ]
          } 

Lessons Learned

1. Framework Complexity vs. Value

Tailwind's Promise: Rapid development with utility classes
Reality:
Build system complexity that outweighs benefits

Sometimes vanilla CSS is the better choice. Modern CSS is incredibly powerful:

  • CSS Grid and Flexbox for layouts
  • CSS Custom Properties for theming
  • CSS Container Queries for responsive design
  • CSS-in-JS when you need dynamic styles

2. AI UX Considerations

Building AI-powered applications requires different UX patterns:

  • Longer wait times are normal and expected
  • ๐Ÿ“ข Clear communication about processing time
  • ๐Ÿ”„ Progressive disclosure of results
  • ๐Ÿ›ก️ Robust error handling for AI failures

3. API Design Evolution

Starting simple and evolving based on frontend needs:

  • ๐ŸŽฏ Backend-driven initially (simple JSON responses)
  • ๐ŸŽจ Frontend-driven enhancement (rich metadata)
  • ๐Ÿ”„ Backward compatibility during transitions

4. The Beauty of Fundamentals

Modern development often pushes us toward complex abstractions, but sometimes the simplest solution is the best:

  • Pure CSS over CSS frameworks
  • Semantic HTML over div soup
  • Progressive enhancement over JavaScript-heavy approaches

Performance Results

After our optimizations:

  • ๐Ÿš€ Build time: 3 seconds (was 45+ seconds with Tailwind debugging)
  • ๐Ÿ“ฆ Bundle size: 15% smaller without Tailwind dependencies
  • Development experience: Hot reload works consistently
  • ๐ŸŽฏ User experience: Clear loading states, beautiful poster images

What's Next?

The Movie Vibes application is now production-ready with:

  • ✅ Beautiful, responsive UI
  • ✅ AI-powered movie analysis
  • ✅ Rich movie metadata with posters
  • ✅ Robust error handling
  • ✅ 2-minute AI operation support

Future enhancements could include:

  • ๐Ÿ—„️ Caching layer for popular movies
  • ๐Ÿ‘ฅ User accounts and favorites
  • ๐ŸŒ™ Dark mode theme
  • ๐Ÿณ Docker deployment setup
  • ๐Ÿงช Comprehensive testing suite

Conclusion: Embrace Simplicity

This journey reinforced a fundamental principle: complexity should solve real problems, not create them.

Tailwind CSS promised to accelerate our development but instead became a roadblock. Pure CSS, with its directness and simplicity, delivered exactly what we needed without the framework overhead.

Building AI-powered applications comes with unique challenges - long processing times, complex data transformations, and user experience considerations that traditional web apps don't face. Focus on solving these real problems rather than fighting your tools.

Sometimes the best framework is no framework at all.
Try Movie Vibes yourself:
  • Backend: mvn spring-boot:run
  • Frontend: npm start
  • Search for your favorite movie and discover its vibe! ๐ŸŽฌ✨

What's your experience with CSS frameworks? Have you found cases where vanilla CSS outperformed framework solutions? Share your thoughts in the comments!

Tech Stack:

  • Spring Boot 3.x + Spring AI
  • React 18 + TypeScript
  • Pure CSS (Custom Design System)
  • Ollama (Local LLM)
  • OMDb API

 

GitHub: tyrell/movievibes 

Building a Model Context Protocol (MCP) Server for Movie Data: A Deep Dive into Modern AI Integration


 

The Challenge: Bringing Movie Data to AI Assistants


As AI assistants become increasingly sophisticated, there's a growing need for them to access real-time, structured data from external APIs. While many AI models have impressive knowledge, they often lack access to current information or specialized databases. This is where the Model Context Protocol (MCP) comes in—a standardized way for AI systems to interact with external data sources and tools.

Today, I want to share my experience building an MCP server that bridges AI assistants with the Open Movie Database (OMDB) API, allowing any MCP-compatible AI to search for movies, retrieve detailed film information, and provide users with up-to-date movie data.

 

What is the Model Context Protocol?

The Model Context Protocol is a emerging standard that enables AI assistants to safely and efficiently interact with external tools and data sources. Think of it as a universal translator that allows AI models to:

  • ๐Ÿ” Search external databases
  • ๐Ÿ› ️ Execute specific tools and functions
  • ๐Ÿ“Š Retrieve real-time data
  • Integrate seamlessly with existing systems

MCP servers act as intermediaries, exposing external APIs through a standardized JSON-RPC interface that AI assistants can understand and interact with safely.

 

The Project: OMDB MCP Server

I decided to build an MCP server for the Open Movie Database (OMDB) API—a comprehensive movie database that provides detailed information about films, TV shows, and series. The goal was to create a production-ready server that would allow AI assistants to:

  1. Search for movies by title, year, and type
  2. Get detailed movie information including plot, cast, ratings, and awards
  3. Lookup movies by IMDB ID for precise identification

 

Technical Architecture

 

Core Technologies

  • Spring Boot 3.5.4 - For the robust web framework
  • Java 21 - Taking advantage of modern language features
  • WebFlux & Reactive WebClient - For non-blocking, asynchronous API calls
  • Maven - For dependency management and build automation
 

MCP Protocol Implementation

The server implements three core MCP endpoints:

 

1. Protocol Handshake (initialize)

{
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {"name": "ai-client", "version": "1.0.0"}
  }
}
 

2. Tool Discovery (tools/list)

Returns available tools that the AI can use:

  • search_movies
  • get_movie_details
  • get_movie_by_imdb_id
 

3. Tool Execution (tools/call)

Executes the requested tool with provided arguments and returns formatted results.

 

Smart Error Handling

One of the key challenges was implementing robust error handling. The server includes:

  • Input validation for required parameters
  • Graceful API failure handling with meaningful error messages
  • Timeout configuration to prevent hanging requests
  • Detailed logging for debugging and monitoring

 

Real-World Challenges and Solutions

 

Challenge 1: HTTPS Migration

Initially, the OMDB API calls were failing due to (my AI assistant ๐Ÿคจ ) using HTTP instead of HTTPS. Modern APIs increasingly require secure connections.

Solution: Updated all API calls to use HTTPS and configured the WebClient with proper SSL handling.

 

Challenge 2: DNS Resolution on macOS

Encountered Netty DNS resolution warnings that could impact performance on macOS systems.

Solution: Added the native macOS DNS resolver dependency:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-resolver-dns-native-macos</artifactId>
    <classifier>osx-aarch_64</classifier>
</dependency>
 

Challenge 3: Response Formatting

Raw OMDB API responses needed to be formatted for optimal AI consumption.

Solution: Created custom formatters that present movie data in a structured, readable format:

private String formatMovieDetails(OmdbMovie movie) {
    StringBuilder sb = new StringBuilder();
    sb.append("๐ŸŽฌ ").append(movie.getTitle()).append(" (").append(movie.getYear()).append(")\n\n");
    
    if (movie.getRated() != null) sb.append("Rating: ").append(movie.getRated()).append("\n");
    if (movie.getRuntime() != null) sb.append("Runtime: ").append(movie.getRuntime()).append("\n");
    // ... additional formatting
    
    return sb.toString();
}
 

Example Usage

Once deployed, AI assistants can interact with the server naturally:

User: "Find movies about artificial intelligence from the 1990s"

AI Assistant (via MCP): Calls search_movies with parameters:

{
  "title": "artificial intelligence", 
  "year": "1990s"
}

Result: Formatted list of AI-themed movies from the 1990s with IMDB IDs for further lookup.

 

Key Features

 

๐Ÿš€ Production Ready

  • Comprehensive error handling
  • Input validation
  • Configurable timeouts
  • Detailed logging

Performance Optimized

  • Reactive, non-blocking architecture
  • Connection pooling
  • Efficient memory usage

๐Ÿ”ง Developer Friendly

  • Complete documentation
  • Test scripts included
  • Easy configuration
  • Docker-ready

๐ŸŒ Standards Compliant

  • Full MCP 2024-11-05 specification compliance
  • JSON-RPC 2.0 protocol
  • RESTful API design

 

Testing and Validation

The project includes comprehensive testing:

# Health check
curl http://localhost:8080/mcp/health

# Search for movies
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "tools/call", 
"params": {"name": "search_movies", 
"arguments": {"title": "Matrix"}}}'
 

Lessons Learned

 

1. Protocol Standards Matter

Following the MCP specification exactly ensured compatibility with different AI clients without modification.

2. Error Handling is Critical

In AI integrations, clear error messages help both developers and AI systems understand and recover from failures.

3. Documentation Drives Adoption

Comprehensive documentation with examples makes the difference between a useful tool and one that sits unused.

4. Modern Java is Powerful

Java 21 features like pattern matching and records significantly improved code readability and maintainability.

 

Future Enhancements

The current implementation is just the beginning. Future enhancements could include:

  • Caching layer for frequently requested movies
  • Rate limiting to respect API quotas
  • Additional data sources (e.g., The Movie Database API)
  • Advanced search features (genre filtering, rating ranges)
  • Recommendation engine integration

 

Try It Yourself

The complete source code is available on GitHub: github.com/tyrell/omdb-mcp-server

To get started:

  1. Clone the repository
  2. Get a free OMDB API key from omdbapi.com
  3. Set your API key: export OMDB_API_KEY=your-key
  4. Run: mvn spring-boot:run
  5. Test: curl http://localhost:8080/mcp/health 

 

Conclusion

Building this MCP server was an excellent introduction to the Model Context Protocol and its potential for enhancing AI capabilities. The project demonstrates how modern Java frameworks like Spring Boot can be used to create robust, production-ready integrations between AI systems and external APIs.

As AI assistants become more prevalent, tools like MCP servers will become essential infrastructure—bridging the gap between AI intelligence and real-world data. The movie database server is just one example, but the same patterns can be applied to any API or data source.

The future of AI isn't just about smarter models; it's about giving those models access to the vast ecosystem of data and tools that power our digital world. MCP servers are a key piece of that puzzle.


 

Want to discuss this project or share your own MCP server experiences? Feel free to reach out or contribute to the project on GitHub!

 

Technical Specifications

  • Language: Java 21
  • Framework: Spring Boot 3.5.4
  • Protocol: MCP 2024-11-05
  • API: OMDB (Open Movie Database)
  • Architecture: Reactive, Non-blocking
  • License: MIT
  • Status: Production Ready
 

Repository Structure

omdb-mcp-server/
├── src/main/java/co/tyrell/omdb_mcp_server/
│   ├── controller/     # REST endpoints
│   ├── service/        # Business logic
│   ├── model/          # Data models
│   └── config/         # Configuration
├── README.md           # Complete documentation
├── test-scripts/       # Testing utilities
└── LICENSE             # MIT License
GitHub: https://github.com/tyrell/omdb-mcp-server 
 
 

Tuesday, July 29, 2025

Building MovieVibes: A Vibe Coding Journey with Agentic AI

 "At first it was just a fun idea — what if a movie recommendation engine could understand the vibe of a film, not just its genre or rating?"

That simple question kicked off one of my most rewarding experiments in Vibe Coding and Agentic AI — powered entirely by Ollama running locally on my machine.

 

Motivation: Coding by Vibe, not by Ticket

Lately, I’ve been inspired by the idea of "Vibe Coding" — a freeform, creative development style where we start with a concept or feeling and let the code evolve organically, often in partnership with an AI assistant. It’s not about Jira tickets or rigid specs; it’s about prototyping fast and iterating naturally.

My goal was to build a movie recommendation app where users enter a movie title and get back a vibe-based summary and some thoughtful movie suggestions — not just by keyword match, but by understanding why someone liked the original movie.

 

Stage 1: The Big Idea

I started with a prompt:

"Take a movie name from the user, determine its vibe using its genre, plot, and characters, and recommend similar movies."

The app needed to:

  • Fetch movie metadata from the OMDb API
  • Use a local LLM (via Ollama) to generate a vibe summary and similar movie suggestions
  • Serve results via a clean JSON API

We scaffolded a Spring Boot project, created REST controllers and services, and started building out the logic to integrate with both the OMDb API and the locally running Ollama LLM.

 

Stage 2: Engineering the Integration

Things were going smoothly until they weren’t. ๐Ÿ˜…

Compilation Errors

When we added the OmdbMovieResponse model, our service layer suddenly couldn't find the getTitle(), getPlot(), etc. methods — even though they clearly existed. The culprit? Missing getters (at least that's what we thought at the time...).


We tried:

  • Manually writing getters ✅
  • Using Lombok’s @Getter annotation ✅
  • Cleaning and rebuilding Maven ✅

Still, values were null at runtime.

 

The Root Cause

Turns out the problem was with URL encoding of the title parameter. Movie titles with spaces (like The Matrix) weren’t properly encoded, which broke the API call. Once we fixed that, everything clicked into place. ๐ŸŽฏ

Note: The AI would never have figured this out by itself. This was just my natural instincts kicking in to guide the AI as I would direct any other human developer. Also, It has been ages since I worked on a Spring boot project with Maven. However, the usual gotchas are still there in the year 2025 ๐Ÿ™„. 

 

Stage 3: Talking to the LLM (via Ollama)

This was where things got really fun.

Instead of relying on cloud APIs like OpenAI, I used Ollama, a local runtime for open-source LLMs. It let me:

  • Run a model like LLaMA or Mistral locally
  • Avoid API keys and cloud latency
  • Iterate on prompts rapidly without rate limits

The app sends movie metadata (genre, plot, characters) to the local LLM with a tailored prompt. The LLM returns:

  • A summarized “vibe” of the movie
  • A list of recommended films with similar emotional or narrative energy

The results were surprisingly nuanced and human-like.

 


Tests, Cleanups, and Git Prep

To make the app production-ready:

  • We wrote integration tests using MockMvc
  • Hid API keys in .env files and excluded them via .gitignore
  • Structured the MovieVibeRecommendationResponse as a list of objects, not just strings
  • Wrote a solid README.md for onboarding others

 

Going Agentic

With the basic loop working, I asked:

How can this app become Agentic AI?

We designed the logic to act more like an agent than a pipeline:

  1. It fetches movie metadata
  2. Synthesizes emotional and narrative themes
  3. Determines recommendations with intent — not just similarity

This emergent behavior made the experience feel more conversational and human, despite being fully automated and offline.

 

Reflections

This project was peak Vibe Coding — no rigid architecture upfront, just a flowing experiment with a clear purpose and evolving ideas.

The use of Ollama was especially empowering. Running an LLM locally gave me:

  • Full control of the experience
  • No API costs or usage caps
  • A deeper understanding of how AI can enhance personal and creative tools

 

Next Steps

For future improvements, I'd love to:

  • Add a slick front-end UI (maybe with React or Tailwind)
  • Let users rate and fine-tune their recommendations
  • Persist data for returning visitors
  • Integrate retrieval-augmented generation for even smarter results

But even as an MVP, the app feels alive. It understands vibe. And that’s the magic. I committed the code to my Github at https://github.com/tyrell/movievibes. All this was done in a few hours since publishing my previous post about Spring AI


A Word on Spring AI

While this project used a more manual approach to interact with Ollama, I’m excited about the emerging capabilities of Spring AI. It promises to simplify agentic workflows by integrating LLMs seamlessly into Spring-based applications — with features like prompt templates, model abstractions, embeddings, and even memory-backed agents.

As Spring AI matures, I see it playing a major role in production-grade, AI-powered microservices. It aligns well with Spring’s core principles: abstraction, convention over configuration, and testability. 

 

Try the idea. Build something weird. Talk to your code. Let it talk back. Locally.

 

UPDATE (01/AUG/2025): Read the sequel of this here

 

Monday, July 28, 2025

Introduction to Spring AI: Bringing the Power of AI to the Spring Ecosystem

Artificial Intelligence is no longer a niche capability—it’s rapidly becoming a foundational element across enterprise applications. Whether you're building smarter chatbots, generating insights from unstructured content, or integrating Large Language Models (LLMs) into your workflows, developers increasingly need streamlined ways to plug AI into real-world systems.

 

That’s where Spring AI steps in.

In this blog post, I’ll introduce Spring AI, a new project from the Spring team that brings first-class support for integrating generative AI and foundation models into Spring-based applications. It’s an exciting addition to the Spring ecosystem that aims to make AI integration as natural as working with data sources or messaging.

 

What is Spring AI?

Spring AI is an open-source project that provides a unified and consistent programming model to work with modern AI capabilities like:

  • Large Language Models (LLMs) such as OpenAI, Azure OpenAI, Hugging Face, and Ollama
  • Embedding Models for semantic search
  • Vector Stores (like Redis, Milvus, Qdrant, Pinecone, and PostgreSQL with pgvector)
  • Prompt Templates, RAG (Retrieval-Augmented Generation) workflows, and tool execution

The project is deeply inspired by Spring Data and Spring Cloud, and brings that same level of abstraction and consistency to AI workflows.

 

Key Features of Spring AI

 

1. Unified LLM API

Spring AI provides a consistent interface across multiple LLM providers like:

  • OpenAI
  • Azure OpenAI
  • Hugging Face
  • Ollama

This allows you to write code once and switch providers with minimal changes.

var response = chatClient.call(new Prompt("Tell me a joke about Spring Boot"));
System.out.println(response.getResult());

2. Prompt Engineering Made Easy

PromptTemplate template = new PromptTemplate("Translate this text to French: {text}");
template.add("text", "Hello, world!");

3. Support for RAG (Retrieval-Augmented Generation)

Integrate AI responses with external knowledge sources using vector search. Spring AI supports various vector stores and offers abstractions for embedding, storing, and retrieving content semantically.

Embedding embedding = embeddingClient.embed("Spring is great for microservices!");
vectorStore.add(new EmbeddingDocument("id-1", embedding, metadata));

4. Integration with Spring Boot

Spring AI is a first-class citizen in the Spring ecosystem. It works seamlessly with Spring Boot and supports features like:

  • Declarative configuration using application.yml
  • Integration with Actuator and Observability
  • Use of @Bean, @Configuration, and dependency injection

5. Tool Execution and Function Calling

Spring AI supports tool calling and function execution—critical for agent-based applications.

 

A Simple Use Case

Let’s say you’re building a customer support chatbot. With Spring AI, you can:

  1. Use OpenAI to handle natural language queries.
  2. Store support articles in a vector database.
  3. Implement RAG to enhance responses using your private knowledge base.
  4. Define functions (e.g., "create support ticket") that the model can call programmatically.

The entire pipeline is manageable using familiar Spring idioms.

 

Why Use Spring AI?

If you’re already using Spring Boot in your backend stack, Spring AI provides:

  • Consistency: Familiar APIs and configuration patterns.
  • Portability: Swap providers or vector stores with minimal refactoring.
  • Flexibility: Fine-grained control over prompts, embeddings, and function calls.
  • Productivity: Rapid prototyping and integration without boilerplate.
 

Getting Started

To get started:

  1. Add Spring AI to your Maven or Gradle project:
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
  1. Configure your provider:
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
  1. Inject and use the ChatClient, EmbeddingClient, or other components in your service.

Official guide: https://docs.spring.io/spring-ai/reference

 

The Future of Enterprise AI with Spring

Spring AI represents a big leap in making AI accessible for mainstream enterprise developers. Instead of reinventing the wheel, teams can build intelligent systems using familiar patterns and strong ecosystem support.

Whether you’re building smart assistants, enhancing search, or enabling decision support, Spring AI offers a solid foundation.

 

I’ll be diving deeper into use cases and tutorials in future posts—stay tuned!

Thursday, November 27, 2008

A typical Open Source SOA

In a recent post, Mike Kavis illustrates Why an Open Source SOA stack makes sense. The following diagram is from his post, which shows how different components from WSO2 and other Open Source vendors fit into place in a typical SOA.


Wednesday, November 12, 2008

Active Endpoints' and WSO2 on the future of SOA development

"This show is a for the community of Java developers and enterprise architects
interested in building a new generation of service-oriented
architecture (SOA) applications. Discussion will include using the
business process execution language (BPEL), the business processing
modeling notation (BPMN) and BPEL4People in an all-in-one visual
orchestration system to create these exciting new BPM applications.
"

Join now for the free 'call-in and chat' conference. Even if you missed it, no problem. It will be available as a podcast later, at the same location.

Thursday, November 06, 2008

Business Mashups are here. How do you make them work?

We have been busy consulting and even conducting a training over the past two weeks, which makes clear Gartner's prediction of Mashups breaking 10% adoption by 2012 realistic. However, when enterprise mashups are user driven, not IT. Having a few best practices in mind will save a lot of trouble in the long term for a CIO.

It is true that the primary task is setting up a Mashup Platform, such as the WSO2 Mashup Server and making sure that the underlying data sources (Web Services, REST APIs etc) are in place and available. But one should at least adopt the following best practices to make his dream of user driven innovation via Mashups a reality.
  1. Train the users on Mashups and your Mashup Platform before anything else. Make it mandatory not optional before even getting an account on your Mashup Platform.
  2. Use a platform that allows users to have a personal version of their own in their local machines. This is the sandbox they create and experiment. Once done, they can upload the Mashups to the enterprise server (either with or without the help of IT), where their masterpiece can be used by others.
  3. Always remember that Mashups are first and foremost compositions of existing data sources in new ways, which means that you need to make sure that an adequate number of data sources are available within the enterprise. If you have a Service Oriented Architecture (SOA), then those services, which make up your SOA provide good Mashup sources.
What if one doesn't have an SOA in place? Well your Mashup Platform itself should be able to help you create services out of the data already stored by your applications. The WSO2 Mashup Server for instance, comes with in-build Data Services support. Which means, if you have data in a database (even a spreadsheet), it can be exposed as a service or a data source.

These tips should be helpful for any enterprise thinking of bringing in Mashups as a Business Integration tool.




Saturday, November 01, 2008

SOA and Dashboards

From the article ...

Situational awareness, thanks to SOA-driven dashboard | Service-Oriented Architecture | ZDNet.com
Roy Schulte, vice president of Gartner, is quoted as observing that the executive dashboard may be among the keys to bridging SOA and Business Process Management. “Business users may not understand SOA, BPM, CEP or XTP [eXtreme Transaction Processing], but they know what they want to see on their dashboard and they may be willing to fund back end architecture and development projects to get more information faster.”
That's why we decided to integrate a Dashboard component in our Mashup Server since version 1.5 months back. I briefly blogged about how we are using it internally to power our dashboards.

We also made sure that we use open standards such as the Gadget Specification by Google (used in iGoogle) in our Dashboard, which means that gadgets made in our Mashup Server will run on other Dashboards following the same specification (iGoogle for instance).

For those interested, my introductory article on converting your Mashup Server to a personalized dashboard for users might be helpful.


Wednesday, October 22, 2008

Sidekicks for your mashup quests ...

Channa's Blog: How to write Mashups
"The Quick Start Guide assumes that the reader just knows he or she wants to create a Mashup and maybe something about JavaScript; nothing much else."
That pretty much sums it up. But I would like to add some more. Channa introduces you to some of the cool tools we've been working on.
  • The Mashup Editor with a skeleton code generator, gives you a running 'Hello World' mashup in just seconds, with a UI AND a Google Gadget
  • The Javascript Stub Generator allows you to create a stub (or wrapper) to any external SOAP Web Service, which you can 'include' in your mashup and use
  • The Scraping Assistant will help you generate XML instructions to scrape web pages
Take these tools for a spin and suggest improvements you would like to see in them. If you run into problems get help form the developers and users who already use these tools.

Wednesday, October 15, 2008

DaaS is a challenge? Not anymore!

AJAX in the Cloud: Save Your Company a Bundle with Your RIA Strategy!
"AJAX apps need to talk to an intermediate server that acts as a proxy between the web client and the database. This means that the AJAX developer has to develop lots of server-side code that coordinates between the proxy and the database. In addition to requiring precious development cycles, the proxy is a performance bottleneck."
I have to respectfully disagree. If you use a solution such as WSO2 Data Services (Apache 2.0 licensed, Free and Open Source software), you would save a lot of trouble. It's just a matter of writing the correct SQL or Stored Procedure and the Data Services solution will expose your result set as a service. In addition, you can configure security and other QoS parameters for your data service.

Bottom line? No server side code, absolute minimum number of development cycles and reduced worry on performance issues (since the solution is tuned by its developers).

Enterprise Mashups among the Top 10 Strategic Technologies for 2009

Gartner Identifies the Top 10 Strategic Technologies for 2009 - MarketWatch

Enterprise Mashups is among Virtualization, Cloud Computing and Web Oriented Architecture in Gartner's list of strategic technologies for 2009. For the past few months, I have been developing a bunch Mashups for our marketing team using the WSO2 Mashup Server. In summary, these Mashups bring together statistics harvested from various sources and present a unified view, which helps them in their decision making.

The most important aspect is the the implementation time, which is in weeks rather than months. The amount of flexibility when you want to mix data up is amazing. In my point of view, Enterprise adoption will involve at least 2 stages. The first stage would be exposing data you want people to work with as services (in the WSO2 Mashup Server I do it mainly via Data Services). This might take a bit of time and expertise. Once you have these services up and running, any user familiar with a bit of javascript would be able to take data from those services and other external services and APIs and come up with amazing results.

In the case of the WSO2 Mashup Server, any Mashup done by a user can be exposed as a service as well. This means that when someone comes up with a cool Mashup, another Mashup author can use that and build on top of it instead of re-inventing the wheel.

Have a look at some of the cool things others have been doing with the WSO2 Mashup Server.

Monday, October 13, 2008

SOAFaces = RIA + SOA

Here's something promising for the Javascript RIA developer, who works constantly with SOAP/REST Web Services as back-ends and is also in touch with his inner GWT :)

SOAFaces allows GWT developers to bring SOA and RIA together. It also gets rid of the RPC involvement, which is a negative when ocnsidering GWT for realworld applications.

"Specifically, the goals of the SOAFaces project include the following:
  1. No need to write GWT RPC code anymore. Use the UniversalClient
    API to talk with POJO services that are packaged in your application
    server and/or talk with Mule accessible services/endpoints all across
    your enterprise and internet. Your GWT application will have convenient
    access to messaging services (SOAP, JMS, ESB ...etc) that can return
    JavaBeans or JSON objects back to the GWT client. All marshaling is
    handled by the framework.
  2. A framework for building SOA GUI
    applications using modular components. Build anything from a simple
    AJAX type applet all the way to a full blown web application.
  3. Package your code as a component and deploy your code as a component.
  4. SOAFaces components are packaged into a simple JAR formatted archive and easily shared, deployed, and executed.
  5. Create
    back-end workflow powered jobs and services that can be scheduled and
    run on the back-end with easy access to web services. Workflow
    properties and configuration rules can be configured using a web GUI."

Saturday, October 11, 2008

How to run a Southwest Airlines Auto Checkin Mashup from your computer



If you are a regular reader, you would know about the Southwest auto check-in mashup and how Southwest decided to use a 'cease and desist' type threat to get it out of circulation. The threat worked, mainly because WSO2 is a reputed company and they were running the mashup as a 'demo'. Not to make money from it.

But I say they can't prevent people running it from their personal computers. Here's a little how-to.
  • Download the Free and Open Source WSO2 Mashup Server (A Windows installer and a .zip file are available. It's a Java program so you need a Java version 1.5 or higher installed too)
  • Install it and run the server as described in the user guide
  • Goto https://localhost:7443/ and give a username for the admin user
  • Download the Southwest Auto Check-in Mashup and extract the zip
  • You will have 2 .js files (alertme.js and southwestAutoCheckin.js) and a folder named southwestAutoCheckin.resources
  • Copy those files and folder to [your-mashup-server-installation-directory]/scripts/[your-username] folder
  • Within a few seconds, the Mashup will be deployed and ready
  • Now go to http://localhost:7762/services/samples/alertme?tryit and select an alerting method (Twitter is the easiest)
  • Finally go to http://localhost:7762/services/samples/southwestAutoCheckin?tryit and you can track a flight and let the mashup take care of the rest. It will alert you what's going on.

"This mashup automatically checks you in online within 5 minutes of the opening of checking in. You still need to print your boarding pass, which is generally easily done at an airport kiosk"





Enjoy !!

Wednesday, October 08, 2008

Mashups, Google Gadgets and Airline Reservations

In a recent blog post, Jonathan explains how to put together an iGoogle compatible gadget for your Mashup. I like his concise explanation of what a gadget is ...
"A widget or gadget is a little program, usually with a cute and compact UI, that runs inside a widget engine. The widget engine generally has the characteristic that a number of widgets can be viewed at once, allowing a user to construct their own digital dashboard of relevant information sources. There are a number of widget technologies under various names – gadgets, widgets, portlets. Some examples of widget engine include the Google Desktop, iGoogle, Windows Vista Sidebar, Windows Live widgets, Yahoo! Widgets, Apple’s Macintosh Dashboard, and lots more."

Then, he follows the previous post with his latest (and apparently very successful) experiment on making an early, automated reservation at Soutwest Airlines using a Mashup.
"This time I successfully checked in online within 5 minutes of the opening of online checkin, even though I was actually in the air on another flight at the time! My new and still under-development southwestAutoCheckin mashup worked brilliantly and gave me one of the lowest boarding numbers I’ve seen."

The WSO2 Mashup Server, making your life that much cooler!


Friday, October 03, 2008

The age of the Android is upon us

Google posted this video of their Android search application today.



There are also reports on device vendors such as Motorola ramping up and expanding their Android forces from 50 to 359 people apparently with Nokia right behind. It seems like most device vendors in the Open Handset Alliance will follow the lead of Motorola and Nokia, which means cheaper handsets as the competition increases.

In the apps market space, companies such as Handaho are already on-board while there are and will be an awesome set of free Android apps for the taking. Interesting times.

Thursday, September 18, 2008

Bring Legacy Data To Your Mashups With The WSO2 Mashup Server

Bring Legacy Data To Your Mashups With The WSO2 Mashup Server | WSO2 Oxygen Tank
Spreadsheets, CSV files and Databases are among the most basic forms of data representation and manipulation. They have been around for ages and probably will be for many years to come. The word 'legacy', meaning that which is handed down from a predecessor, is often used in the context of these technologies and data withinm. In a 'service oriented' world, challenges of integrating such legacies with the present generation of applications is addressed by products such as the WSO2 Data Services Solution. The WSO2 Mashup Server embeds the WSO2 Data Services solution from version 1.5, enhancing the agile service composition capabilities already present in the Mashup Server. In this tutorial, we will go through the steps involved in exposing a Microsoft Excel preadsheet as a service using the WSO2 Mashup Server Web Console.


My latest tutorial on one of the cool new features in the WSO2 Mashup Server's most recent release; Data Services. I had fun writing it and creating the the sample Mashup. Hope you guys have fun trying the tutorial out ....

Wednesday, August 27, 2008

Google API Libraries for Google Web Toolkit

Google Web Toolkit Blog: Release Candidate now available: the Google API Libraries for Google Web Toolkit
The project is a collection of libraries that provide Java language bindings and API specific plumbing for some Google JavaScript APIs. The goal is to make it easy for developers to use these JavaScript APIs with GWT. Libraries available at this time include a new version of Gears, as well as new libraries for Gadgets and the Google AJAX Search API.

Ever since the term AJAX was coined by Mr. Garret in 2005 and the group of technologies under the umbrella of AJAX appeared on the developer radar, I have worked with numerous so called AJAX Toolkits. GWT was one of the first and I was impressed with it then as I am now. They still have my tutorial on their Wiki. One of the first apart from the standard Getting Started documentation.

Since then I have seen quite a few toolkits chosen over GWT only to crash n' burn when battle tested. The very first prototype I did using GWT was for a large European Telco. It was a graphical, web based tool to model Web Services Orchestration.

The client was impressed and the tool is 'still' in use and evolving. As a matter of fact, I have seen them (them as in the architects from the client and the company I was working for) present it in a few SOA conferences. It just can't get any better than that.

Here's a final question for those who talk crap about GWT (of late, I have come across a few). How many applications have you written with it? I have 'actually' written code with GWT, YUI, DoJo and Prototype. So when I say one toolkit is better than the other it's not just 'talk' bitch.. I have scars to prove it ...


Saturday, August 09, 2008

WSO2 Mashup Server 1.5.1



We just released a point version consisting of fixes to some issues we felt were critical. Download and take it for a spin.

Monday, July 21, 2008

A Mashup Platform, that can double as iGoogle

The WSO2 Mashup Server 1.5 is out.

Check this article on a Mashup platform that not only allows you to create mashups using Web Services, RSS Feeds and Screen Scrapes, but also lets you create your own version of iGoogle, where users can import iGoogle gadgets as well as generate iGoogle gadgets for the mashups they create.