Bring Spring Middleware into a service without hiding how the system works.
Spring Middleware does not replace Spring Boot. It adds a platform layer for service registration, declarative communication, topology awareness, messaging, and infrastructure consistency. The goal is to get a service running quickly while keeping the architecture explicit.
What you need to start
A typical service imports the platform modules it needs, keeps its business code in its own modules, and enables platform capabilities through regular Spring Boot configuration.
Recommended approach
Import the BOM or shared dependency management, then add the specific runtime modules your service needs. This keeps versions aligned across the platform and avoids dependency drift between services.
Lightweight approach
Add only the modules you need with explicit versions. This works for smaller integrations, but the BOM remains the cleaner option when multiple services share the same platform baseline.
Minimal service structure
Spring Middleware fits naturally into a modular service layout. Business logic stays in your own codebase, while the platform layer handles infrastructure concerns consistently.
*-api — shared contracts and DTOs*-core — business logic*-boot — Spring Boot runtime moduleRuntime integration
The *-boot module usually depends on Spring Middleware platform modules such as
app, messaging modules, GraphQL support, or data integrations depending on the
service role.
Startup flow
The initial integration is straightforward: add the right modules, keep a normal Spring Boot application, register your resources, and configure the control plane endpoint.
Add platform dependencies
Import dependency management and add the Spring Middleware modules required by your service.
Keep a standard Boot application
No custom runtime model is required. A regular @SpringBootApplication remains
the service entry point.
Register resources and clients
Expose controllers with @Register and use @MiddlewareClient for
declarative cross-service communication.
Configure the control plane
Point the service to the Registry and enable the platform capabilities that apply to your runtime.
Dependency management
In most cases, the cleanest entry point is version alignment through dependency management, followed by adding only the modules the service actually uses.
Managed versions
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.github.spring-middleware</groupId>
<artifactId>app</artifactId>
<version>${spring-middleware.app.version}</version>
</dependency>
<dependency>
<groupId>io.github.spring-middleware</groupId>
<artifactId>api</artifactId>
<version>${spring-middleware.api.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
Runtime modules
<dependencies>
<dependency>
<groupId>io.github.spring-middleware</groupId>
<artifactId>app</artifactId>
</dependency>
<dependency>
<groupId>io.github.spring-middleware</groupId>
<artifactId>kafka-core</artifactId>
</dependency>
</dependencies>
The important point is not importing everything. The platform is modular. Start with the small set of modules your service needs, but keep versions aligned through the BOM whenever possible.
Application entry point
Spring Middleware does not require a special application model. A standard Boot application remains the runtime entry point.
@SpringBootApplication
public class CatalogApplication {
public static void main(String[] args) {
SpringApplication.run(CatalogApplication.class, args);
}
}
Declarative clients and registration
Cross-service communication and topology registration are both explicit. Services declare remote contracts and register their own resources in the control plane.
Declarative client
@MiddlewareClient(service = "product")
public interface ProductClient {
@GetMapping("/products/{id}")
ProductDto getProduct(@PathVariable("id") UUID id);
}
Registered controller
@RestController
@Register
@RequestMapping("/catalogs")
public class CatalogController {
// endpoints
}
Minimal configuration
Most services start with registry configuration, client security, and only the infrastructure sections that are relevant to their runtime behavior.
Registry
spring:
middleware:
registry:
url: ${REGISTRY_ENDPOINT:http://localhost:8080/registry}
enabled: true
Client configuration
middleware:
client:
registry-endpoint: ${REGISTRY_ENDPOINT:http://localhost:8080/registry}
product:
security:
type: OAUTH2_CLIENT_CREDENTIALS
api-key: ${API_KEY_PRODUCT_SERVICE:default-product-api-key}
oauth2:
client-id: ${OAUTH2_CLIENT_ID_PRODUCT_SERVICE:product-service}
client-secret: ${OAUTH2_CLIENT_SECRET_PRODUCT_SERVICE}
token-uri: ${OAUTH2_TOKEN_URI_PRODUCT_SERVICE:http://keycloak:8080/realms/spring-middleware/protocol/openid-connect/token}
Kafka
kafka:
bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS:localhost:9092}
create-missing-topics: true
topics:
catalog-events:
partitions: 5
replication-factor: 3
Logging trigger
middleware:
log:
apiKey: ${MIDDLEWARE_LOG_API_KEY:}
Security, build, and local execution
The platform supports service-level and client-level security, but the basic local workflow remains familiar: package the Boot module and run the jar or start it from the IDE.
Security model
Configure protected paths and client-side authentication depending on the service role. Supported patterns include API key, passthrough security, and OAuth2 client credentials.
Build
mvn -T 1C -DskipTests clean package
Run
java -jar target/your-service-boot-<version>.jar
Practical notes
A few details usually matter early: version alignment, local topic creation, Docker build context, and configuration binding in tests.
- Use the BOM to keep module versions aligned across services.
- Enable topic auto-creation locally, but manage topics explicitly in production.
- Check
.dockerignoreif Docker builds cannot see the generated jar. - Make sure required configuration properties can bind in tests.
What this page is for
This page is intentionally narrow. It helps a service cross the initial integration line. Deeper runtime behavior belongs in the architecture, registry, communication, messaging, GraphQL, security, and error model pages.
Continue with the platform building blocks
Once the service is bootstrapped, the next step is understanding how the platform behaves at runtime.