Building Portable Cloud Functions with Spring Cloud Function and Hexagonal Architecture -  Part 1 (GCP)

Building Portable Cloud Functions with Spring Cloud Function and Hexagonal Architecture - Part 1 (GCP)

Serverless functions have revolutionized how we build and deploy applications. With just a few clicks, you can deploy functions that respond to HTTP requests, process events, or integrate with messaging systems across major cloud providers. However, there's a significant challenge: vendor lock-in.

Each cloud provider offers its own framework, runtime, and deployment model:

  • AWS Lambda with its proprietary handler interface
  • Azure Functions with its specific triggers and bindings
  • Google Cloud Functions with its own function signatures

What if you could write your business logic once and deploy it anywhere?


The Solution: Spring Cloud Function + Hexagonal Architecture

Spring Cloud Function provides a functional programming model that abstracts away cloud-specific implementations. You write pure business functions, and Spring Cloud Function handles the adaptation to different cloud runtimes.

Hexagonal Architecture (Ports and Adapters) takes this further by isolating your domain logic from external concerns like databases, messaging systems, and web frameworks.

Together, they deliver:

  • Portability — Same code runs on GCP, AWS, and Azure
  • Testability — Business logic can be tested in isolation
  • Maintainability — Clear separation of concerns
  • Flexibility — Easy to swap infrastructure components


The Demo: Task Management System

I'll demonstrate this approach with a Task Management System that implements comprehensive business rules for each CRUD operation:

Business Rules Implementation

Create Operations:

  • Users cannot create more than 5 high-priority tasks per day
  • Task descriptions must be unique per user per day
  • Users cannot have more than 50 open tasks
  • Tasks must have valid priorities (LOW, MEDIUM, HIGH)

Read Operations:

  • Users can only access their own tasks

Update Operations:

  • Completed tasks cannot be modified

Delete Operations:

  • Users can only delete their own tasks

These rules live in the domain layer, completely independent of cloud infrastructure.


Architecture Deep Dive

Package Structure

Article content
Package Structure

Architecture Principle: Dependencies point inward. The domain knows nothing about Firestore, HTTP, or GCP.

Core Implementation Highlights

1. Rich Domain Model with Value Objects

Article content
Rich Domain Model with Value Objects

2. Clean Use Case Interfaces

Article content
Clean Use Case Interfaces

3. Application Service (Orchestration)

Article content
Application Service (Orchestration)

4. Spring Cloud Function Adapter

Article content
Spring Cloud Function Adapter

5. GCP-Specific Repository Implementation

Article content
GCP-Specific Repository Implementation

GCP Deployment with Infrastructure as Code

Maven Configuration

Article content
Maven Configuration

Build and Deploy

Article content
Build and Deploy

Terraform Configuration

Article content
Terraform Configuration

Testing in Action

Function Routing

Spring Cloud Function uses a routing mechanism to direct requests to the correct function:

Article content
Function Routing

Business Rules Validation

Article content
Business Rules Validation

Key Benefits Demonstrated

1. Pure Business Logic

The domain layer contains no GCP-specific code. Rules like "max 5 high-priority tasks per day" are expressed in pure Java, making them:

  • Easy to understand
  • Simple to test
  • Cloud-agnostic

2. Testable Architecture

Article content
Testable Architecture

3. Infrastructure Flexibility

Swapping from Firestore to DynamoDB requires only:

  • New outbound adapter implementation
  • Configuration change
  • Zero domain logic changes


What's Coming Next

This GCP implementation establishes our foundation. In the upcoming parts of this series:

Part 2: AWS Implementation

  • Same domain code
  • AWS Lambda adapter
  • DynamoDB repository
  • Terraform for AWS infrastructure

Part 3: Azure Implementation

  • Same domain code
  • Azure Functions adapter
  • Cosmos DB repository
  • Terraform for Azure infrastructure


The Power of Abstraction

By combining Spring Cloud Function with Hexagonal Architecture, we've achieved something remarkable: true cloud portability without compromising functionality.

Our task management system runs identically across cloud providers because:

  • Business rules live in the domain — cloud-agnostic
  • Spring Cloud Function handles runtime adaptation — no vendor lock-in
  • Ports and Adapters isolate infrastructure — easy to swap components

Get Started

Ready to explore cloud-portable serverless applications?

🔗 Complete source code: GitHub Repository

📋 What you'll find:

  • Full implementation with comprehensive tests
  • Terraform infrastructure definitions
  • Automated testing scripts
  • Architecture validation tests
  • Deployment documentation

Star the repo if you find this approach valuable!


Next up: Part 2 will show how the same business logic runs seamlessly on AWS Lambda with DynamoDB. Follow me to get notified when it drops!

Great article ! Thanks for sharing!

Like
Reply

Thanks for sharing, awesome

Great approach to tackling vendor lock-in in the server-less space. Using Spring Cloud Function to write portable code is a huge advantage for developers.

This is a great post and a very compelling case for using Spring Cloud Function to combat vendor lock-in. You've clearly articulated a significant pain point for developers and presented a powerful, elegant solution. The focus on pure business logic and clean architecture principles is a perfect way to highlight the long-term benefits of this approach. I'm looking forward to reading your article on the AWS and DynamoDB implementation in Part 2!

To view or add a comment, sign in

More articles by Erick Beloti

Explore content categories