• Stars
    star
    219
  • Rank 181,133 (Top 4 %)
  • Language
    Kotlin
  • License
    MIT License
  • Created over 1 year ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An example of Clean Architecture in Spring. Demo app for Spring 2023

Welcome to the Spring Shoe Store!

A demonstration app built for Spring I/O 2023 to present Clean Architecture principles in Spring

Overview

As mentioned, this repository is meant to show off a key techniques to attempt to achieve Clean Architecture:

Individual Components

The application is broken into three individually tested and built Gradle modules; something the Book would call 'Components'.

  • store-core: contains all the Entities, Use Cases, DTOs, Interfaces, and other classes necessary to fulfill the business logic. Has no direct dependencies on the other components, nor any external systems (e.g. a database). It is ignorant and agnostic of anything that is not Core Business Rules.
  • store-details: contains the implementation "Details"; the interface implementations responsible for actually communicating with external systems, performing I/O, etc... as well as supporting classes necessary to make that work.
  • store-app: contains the Spring components, configuration, application lifecycle concerns, and is currently the location of HTTP (e.g. controllers.). This component is the place of actual 'integration'; where the app comes together. It is also the location of Integration tests.

The three are meant to be illustrative or a starting point; in a real application you may have more than three. For example, the current details component could be broken up into multiple ones, each for redis, postgres, etc. The http concerns could be extracted.

Dependency directionality

All dependencies should point 'inward', that is, everything depends on Core, but Core has no knowledge of the other components. Practically, this is largely achieved by liberal use of Interfaces and small data classes contained within the Core package. Other components are thus dependent on core by adhering to the interface.

The Repository pattern is also heavily used.

Be advised that this code is truly, truly horrendous. It should be used for architecturalreference - or entertainment - purposes only

Encapsulation and Isolation

Concerns of the Component should be contained within the Component.

  • the details component marks any non-interface-implementation classes with the internal keyword. In Kotlin, this ensures that the class can not be used by jars / artifacts outside the current module. This pairs nicely with the notion of using multiple components like we do here.
  • The http layer in store-app contains its own API objects, and translates the internal DTOs to an API-consumer-dedicated object. This also reduces the cross-boundary dependencies; without these API objects the api consumers would be directly dependent on classes contained in core.

Yes this results in more mapping code, but this is a small price to pay for the loose coupling we achieve with this architectural style.

Ignorance of Environment

The system has no notion of traditional environments (e.g. DEV, TEST, PROD, etc). Instead, it utilizes environment variables to adjust configuration. This means that the system can use Integration Tests with real external dependencies just as easily as if it were running locally, or in a CI pipeline, or in a k8s cluster.

Speaking of testing, this application makes heavy use of TestContainers, creating a real Postgres, Redis, and simulates AWS using the wonderful Localstack.

To run the tests, try ./gradlew clean test. To demonstrate the advantages of the repository pattern, this repo is set up to swap out the storage of Orders from using Postgres to using DynamoDb. To do so:

  1. Verify the current tests work (./gradlew test)
  2. Find the getOrderRepository() Bean function located in CoreConfig within the store-app component.
  3. Replace the return PostgresOrderRepository(jdbcTemplate) line with return DynamoDbOrderRepository(dynamoDbClient).
  4. Run the tests once again (./gradlew clean test)
  5. The tests should still pass!

More Repositories

1

spring-bikeshed

An example app to demonstrate Event Sourcing concepts for Spring I/O 2024 AND to learn Vite w/React
Kotlin
65
star
2

backbone-vertebrae

Sample structure for Single Page Web Application code, based around Backbone and RequireJS
JavaScript
7
star
3

MarkdownPreview

A package for Sublime Text 2 that uses MultiMarkdown (mmd) to generate previews of a markdown buffer.
Python
7
star
4

Grails-Switcher

Small Groovy app to switch your current Grails version via a command line app
Groovy
7
star
5

spark-cass-spring-demo

A small app demoing Spark + Cassandra usage within a spring boot app
Java
6
star
6

reactive-movie-demo

A demo app showing how rxJava (rxGroovy), rxJS, and Ratpack can all work together
JavaScript
6
star
7

greach2014-es-demo

Sample App for a presentation at Greach 2014
JavaScript
5
star
8

reactive-ratpack-demo

A companion to a talk on being Reactive at all layers of the stack
Groovy
4
star
9

geo-cluster

Geographic KMeans clustering in Groovy/Java
Groovy
4
star
10

fluentconf2013-hacks

Various hacks using grunt that we worked on during FluentConf 2013
JavaScript
3
star
11

eventsource-ratpack-reference

A reference app for using ThirdChannel's eventsource library... in a Ratpack app
Groovy
3
star
12

gr8conf-2012-workshop

Presentation materials, instructions, and sample app for a workshop I'm holding during Gr8Conf 2012. Participants will gain hands on experience building a Backbone.js based application
JavaScript
3
star
13

jooq-demo

A very small demo showcasing the jOOQ library
Groovy
2
star
14

greach2015-reactive-demos

Some small spring boot apps demonstrating some reactive concepts... at first in Akka and RxGroovy
Groovy
2
star
15

event-source-demo

Reference app for doing some Event Sourcing work
Groovy
2
star
16

oreillysacon-eventsourcing-demo

Demo of an Event Sourcing app I put together for the inaugural O'Reilly Software Architecture Conference
JavaScript
2
star
17

event-driven-arch-club

A sample project in which to practice event-driven programming with Spring and Kafka
Java
2
star
18

presentationTimer

Adds a small little fixed-position timer to the your page. Toy script that I use in some presentations to time myself.
JavaScript
1
star