Getting Started

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 module

Runtime 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.

1

Add platform dependencies

Import dependency management and add the Spring Middleware modules required by your service.

2

Keep a standard Boot application

No custom runtime model is required. A regular @SpringBootApplication remains the service entry point.

3

Register resources and clients

Expose controllers with @Register and use @MiddlewareClient for declarative cross-service communication.

4

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
}
Registry-driven resolution Explicit contracts Consistent error propagation Trace context propagation

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 .dockerignore if 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.