DEV Community

Said Olano
Said Olano

Posted on

Building Python-to-Spring Boot Microservices: A Complete Integration Guide

Building Python-to-Spring Boot Microservices: A Complete Integration Guide

Introduction: The Era of Polyglot Microservices

In modern software architecture, microservices have become the de facto standard for building scalable and maintainable applications. One of the most common challenges in this transition is the need to integrate services written in different programming languages. This article will guide you step-by-step through creating a Python microservice that communicates securely and efficiently with another microservice built in Spring Boot.

Polyglot architecture is not a trend—it's a reality. Organizations adopt the most appropriate language for each task: Python for machine learning and data analysis, Java/Spring Boot for critical and scalable systems, Node.js for real-time applications. The ability for these services to communicate with each other is fundamental.

Why Integrate Python with Spring Boot?

Real-World Use Cases

  1. Real-Time Data Analysis: A Python service with pandas and scikit-learn executes analysis while Spring Boot handles transactions.
  2. Specialized Microservices: Python for NLP and computer vision; Spring Boot for business logic and persistence.
  3. Legacy Systems: Expand capabilities of existing Java systems with new Python functionality.
  4. Distributed Teams: Different teams work with their preferred languages, integrated through REST APIs.

Advantages of This Combination

  • Technology Flexibility: Choose the right tool for each problem
  • Independent Scalability: Both services scale according to their needs
  • Easier Maintenance: Specialized teams for each technology
  • Gradual Adoption: Migrate or expand capabilities without rewriting everything

Solution Architecture

Our architecture consists of:

┌─────────────────────┐
│   Client/UI         │
└──────────┬──────────┘
           │
      ┌────▼─────────┐
      │  Spring Boot  │ (Port 8080)
      │  Service      │
      │  (Orchestrator)
      └────┬──────────┘
           │ REST Call
           │
      ┌────▼──────────┐
      │  Python       │ (Port 5000)
      │  Microservice │
      │  (Processor)  │
      └────┬──────────┘
           │
      ┌────▼──────────┐
      │  Database     │
      │  (Data)       │
      └───────────────┘
Enter fullscreen mode Exit fullscreen mode

Step 1: Building the Python Microservice

Project Setup

mkdir python-microservice
cd python-microservice
python3 -m venv venv
source venv/bin/activate
pip install flask flask-cors requests python-dotenv
Enter fullscreen mode Exit fullscreen mode

Main Application (app.py)

from flask import Flask, jsonify, request
from flask_cors import CORS
from dotenv import load_dotenv
import os
import logging

load_dotenv()
app = Flask(__name__)
CORS(app)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

from routes.api import api_bp
app.register_blueprint(api_bp)

@app.route('/health', methods=['GET'])
def health_check():
    return jsonify({
        'status': 'healthy',
        'service': 'python-microservice',
        'version': '1.0.0'
    }), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=int(os.getenv('FLASK_PORT', 5000)))
Enter fullscreen mode Exit fullscreen mode

Core Service (services/processor.py)

import requests
import logging
from typing import Dict, Any, Optional
from config import config

logger = logging.getLogger(__name__)

class DataProcessor:
    def __init__(self):
        self.spring_url = config.SPRING_BOOT_URL
        self.timeout = config.REQUEST_TIMEOUT

    def send_to_spring_boot(self, endpoint: str, data: Dict[str, Any], method: str = 'POST'):
        try:
            url = f"{self.spring_url}{endpoint}"
            if method.upper() == 'POST':
                response = requests.post(url, json=data, timeout=self.timeout)
            else:
                response = requests.get(url, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            logger.error(f"Error: {str(e)}")
            raise

processor = DataProcessor()
Enter fullscreen mode Exit fullscreen mode

Step 2: Building the Spring Boot Microservice

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-microservice</artifactId>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
Enter fullscreen mode Exit fullscreen mode

UserService.java

@Service
public class UserService {
    private final RestTemplate restTemplate;
    @Value("${python.microservice.url}")
    private String pythonMicroserviceUrl;

    public UserResponse processUserData(UserRequest request) {
        try {
            String pythonUrl = pythonMicroserviceUrl + "/api/process";
            UserResponse response = restTemplate.postForObject(
                pythonUrl, request, UserResponse.class
            );
            return new UserResponse(true, request.getUserId(), 
                "Processing completed", response);
        } catch (Exception e) {
            return new UserResponse(false, request.getUserId(), 
                "Error: " + e.getMessage(), null);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Docker Compose

version: '3.8'
services:
  python-service:
    build:
      context: ./python-microservice
    ports:
      - "5000:5000"
    environment:
      - SPRING_BOOT_URL=http://spring-boot-service:8080
  spring-boot-service:
    build:
      context: ./spring-boot-microservice
    ports:
      - "8080:8080"
Enter fullscreen mode Exit fullscreen mode

Integration Testing

curl -X POST http://localhost:5000/api/process \
  -H "Content-Type: application/json" \
  -d '{"user_id": 123, "action": "update"}'
Enter fullscreen mode Exit fullscreen mode

Production Considerations

  1. Authentication: JWT or OAuth2
  2. Circuit Breaker: Resilience4j for fault tolerance
  3. Rate Limiting: Protect endpoints from abuse
  4. Observability: Distributed logging and tracing
  5. Monitoring: Metrics and alerting

Best Practices

  • Use API versioning for backward compatibility
  • Implement proper error handling and logging
  • Use containerization for consistent deployments
  • Document API contracts thoroughly
  • Implement health checks for readiness probes

Conclusion

Integrating Python with Spring Boot empowers you to build modern, scalable microservices. Leverage each language's strengths to create resilient systems. The future of software development is polyglot—choose the right tool for each problem.

Top comments (0)