Skip to content

kstojanovski-work/spring-boot-hexagonal-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Spring Boot Hexagonal Architecture Demo

This project is a small shop-ordering API designed to make hexagonal architecture easy to see.

The important rule is: business code does not depend on Spring MVC, Spring Data JPA, H2, or HTTP. Those technologies sit in adapters around the application core.

Architecture

HTTP client
   |
   v
adapter/in/web
   |
   v
application/port/in  <--- use-case interfaces
   |
   v
application/service  <--- orchestration
   |
   v
application/port/out <--- persistence/number-generator contracts
   |
   v
adapter/out/*

Package Tour

domain/model

Pure business objects: Order, OrderLine, Product, Money. There are no Spring or JPA annotations here.

application/order/*

Order use cases. PlaceOrderService, GetOrderService, CancelOrderService, and DeleteOrderService each coordinate one use case and depend only on ports.

application/*/port/out

Outbound ports. These describe what the application needs from the outside world: loading products, loading orders, saving orders, deleting orders, and generating order numbers.

adapter/in/web

Inbound adapter. OrderController translates HTTP JSON into an application command.

adapter/out/persistence

Outbound adapter. JPA entities and Spring Data repositories translate between database rows and domain objects.

adapter/out/number

Outbound adapter. Generates order numbers.

config

Spring wiring. This is where Spring creates the application service and injects adapter implementations into its ports.

Run It

mvn spring-boot:run

Open the browser UI:

http://localhost:8080

The UI can:

  • create orders
  • show created orders in a table
  • fetch an order by id
  • cancel an order
  • delete an order from the database
  • fetch seeded products
  • show the latest API response

If port 8080 is already in use, start on another port:

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=18080

Then open:

http://localhost:18080

API Examples

Create an order:

curl -i -X POST http://localhost:8080/orders \
  -H 'Content-Type: application/json' \
  -d '{
    "customerEmail": "learner@example.com",
    "items": [
      {
        "productId": "11111111-1111-1111-1111-111111111111",
        "quantity": 2
      }
    ]
  }'

The response includes the generated id. Use it to fetch the order:

curl http://localhost:8080/orders/{id}

List created orders:

curl http://localhost:8080/orders

Cancel an order:

curl -i -X POST http://localhost:8080/orders/{id}/cancel

This keeps the order in the database and changes its status to CANCELLED.

Delete an order:

curl -i -X DELETE http://localhost:8080/orders/{id}

This removes the order from the database. A later GET /orders/{id} returns 404.

Fetch a product:

curl http://localhost:8080/products/11111111-1111-1111-1111-111111111111

Test It

Run the tests:

mvn test

Run the fast unit tests without Spring integration tests:

mvn test -Dtest='!*IntegrationTest'

Learning Checklist

  1. Start with PlaceOrderService.
  2. Notice that it depends on interfaces from application/port/out, not repositories.
  3. Follow LoadProductPort to ProductPersistenceAdapter.
  4. Notice that JPA entities are not the domain model.
  5. Compare CancelOrderService with DeleteOrderService; one changes domain state, the other removes persistence state.
  6. Read the service tests; they test the use cases without Spring.
  7. Read OrderControllerIntegrationTest; it tests full adapter-to-adapter flows.

Example Products

The app starts with three H2 products from src/main/resources/data.sql:

Product ID
Clean Architecture Book 11111111-1111-1111-1111-111111111111
Domain-Driven Design Notes 22222222-2222-2222-2222-222222222222
Refactoring Mug 33333333-3333-3333-3333-333333333333

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors