Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Better Monoliths – Modulithic Applications with Spring Boot

Building Better Monoliths – Modulithic Applications with Spring Boot

How to improve the design of your monolithic applications build with Spring Boot.

Oliver Drotbohm

November 06, 2019
Tweet

More Decks by Oliver Drotbohm

Other Decks in Programming

Transcript

  1. Modulithic Applications

    with Spring Boot
    Building better monoliths
    Oliver Drotbohm ƀ [email protected]
    / odrotbohm

    View Slide

  2. 2

    View Slide

  3. Monolith VS. Microservice
    3
    Module

    A
    Module

    B
    Module

    C
    Module

    B
    Module

    C
    Module

    A
    Bounded Context Deployment Unit Internal invocation External invocation

    View Slide

  4. Monolith
    4
    The application packages the implementation of multiple
    Bounded Contexts as a single deployment unit.
    Easy to refactor
    Easy to test the overall system
    Likely to degrade unless explicitly managed
    Harder to test individual Bounded Contexts

    View Slide

  5. Microservices
    5
    A bounded context defines the boundaries of the deployment
    artifact. Often parts of the context are even deployed as
    separate processes.
    ○ Bounded Context interaction is remote
    ○ Testing individual modules
    Hard to refactor context boundaries
    Hard to test the overall system

    View Slide

  6. How to maintain
    structure in a
    monolithic
    codebase?
    6
    !

    View Slide

  7. Design goals
    7
    1. Minimally invasive
    As little additional metadata as possible required. Advanced
    customizations might need additional information.
    2. Test support
    Individual modules should be testable standalone.
    3. Minimize distance to development workflow
    Feedback about architecture violations as fast as possible.

    View Slide

  8. Development workflow
    8
    Compiler Tests Build Runtime
    Distance to edit / run cycle
    Where do I want my checks to live?

    View Slide

  9. The Sample Codebase
    https://github.com/st-tu-dresden/salespoint
    9

    View Slide

  10. 10
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  11. Moduliths
    https://github.com/odrotbohm/moduliths
    Binaries available from https://repo.spring.io
    11

    View Slide

  12. Moduliths
    12
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.

    View Slide

  13. Package Conventions
    13
    ….modulith
    ….modulith.moduleA
    ….modulith.moduleB
    Visibility modifiers and the
    compiler enough to hide
    internals.

    View Slide

  14. Moduliths
    14
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. Simple set of access rules and API to verify
    Only access components in module API packages.

    View Slide

  15. Access Rules
    15
    Moduliths verifies a couple of rules imposed on your modules.
    No cyclic dependencies
    Only allows explicitly allowed dependencies
    Prevents field injection "

    View Slide

  16. Module dependency verification
    DEMO
    16

    View Slide

  17. Access Rules
    17
    Moduliths verifies a couple of rules imposed on your modules.
    No cyclic dependencies
    Only allows explicitly allowed dependencies
    Prevents field injection "
    Use module base package as API package

    View Slide

  18. API Package Convention
    18
    ….modulith
    ….modulith.moduleA
    ….modulith.moduleB
    Visibility modifiers and the compiler enough to hide internals.

    View Slide

  19. API Package Convention
    19
    ….modulith
    ….modulith.moduleA
    ….modulith.moduleA.internal
    ….modulith.moduleB
    ….modulith.moduleB.internal
    Access to components residing in internal packages

    forbidden and checked during tests.

    View Slide

  20. Moduliths
    20
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. Simple set of access rules and API to verify
    Only access components in module API packages.
    3. Test support to bootstrap modules
    Integration with Spring test context framework and Spring
    Boot integration test support to limit bootstrap (component
    & entity scanning) to only the involved packages.

    View Slide

  21. Web
    Business logic
    Data access
    @Data…Test
    Module A Module B Module C
    @WebMvcTest
    @…Test ?

    View Slide

  22. 22
    package com.acme
    @SpringBootApplication
    class MyApplication { … }
    package com.acme.moduleA
    @ModuleTest // Instead of @SpringBootTest
    class MyModuleTests { … }
    Applies package conventions
    Bootstraps single module for test

    View Slide

  23. 24
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  24. Single module bootstrap
    DEMO
    25

    View Slide

  25. Orders
    28
    Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  26. Detect and remove violation
    DEMO
    29

    View Slide

  27. 30
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    Event
    Event publication

    View Slide

  28. Dependency types
    32
    1. Simple type dependency
    References to aggregates and entities of other modules.
    2. Component dependency
    References to other Spring beans, required to bootstrap the
    module
    3. Events & event listeners
    Dependency on some other module’s event type. Interesting
    as they’re great hooks for testing.
    #☝Avoid!

    View Slide

  29. 33
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    Event
    Event publication

    View Slide

  30. Multi module bootstrap
    DEMO
    34

    View Slide

  31. Bootstrap modes
    35
    1. Standalone
    Bootstraps the module the test is contained in. Components
    in other modules the bootstrapped module depends on
    need to be provided through @MockBean.
    2. Direct dependencies
    Bootstraps the module including the modules it directly
    depends on. Transitive dependencies have to be mocked just
    like in standalone mode.
    3. All dependencies
    Bootstraps the entire sub-tree of modules starting from the
    current one.

    View Slide

  32. Moduliths
    36
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. Simple set of access rules and API to verify
    Only access components in module API packages.
    3. Test support to bootstrap modules
    Integration with Spring test context framework and Spring
    Boot integration test support to limit bootstrap (component
    & entity scanning) to only the involved packages.
    4. Documentation support
    PlantUML integration via Simon Brown’s Structurizr to
    document module structure and dependency types.

    View Slide

  33. Documentation
    DEMO
    37

    View Slide

  34. Tool ecosystem and
    alternative approaches
    38

    View Slide

  35. Multiple Artifacts
    39
    Every module port becomes a dedicated build artifact.
    Dedicated control over dependencies
    Test scope is defined by the artifact
    Potential explosion of number of artifacts
    Internal structure visible to the outside

    View Slide

  36. Java Module System
    40
    Every module becomes a Java 9+ module.
    ○ Strong coupling between module and artifact
    ○ Semantics of the „opens“ keyword
    ○ No test support

    View Slide

  37. External Tools
    41
    External tools (e.g. jQAssistant, Sonargraph, jDepend)
    integrated into the build and executed in the CI environment
    are used to signal structural violations.
    Most extensive option
    Distance to development workflow

    View Slide

  38. Development workflow
    42
    Compiler Tests Build Runtime
    Moduliths
    Maven Modules
    Jigsaw / OSGi
    jQA etc.
    Applies rules Invasiveness (bigger is stronger)

    View Slide

  39. Moduliths
    43
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. Simple set of access rules and API to verify
    Only access components in module API packages.
    3. Test support to bootstrap modules
    Integration with Spring test context framework and Spring
    Boot integration test support to limit bootstrap (component
    & entity scanning) to only the involved packages.
    4. Documentation support
    PlantUML integration via Simon Brown’s Structurizr to
    document module structure and dependency types.

    View Slide

  40. Resources
    44
    Moduliths
    Project website on GitHub
    Majestic Modular Monoliths
    Video on Youtube
    Modular Monoliths
    Simon Brown – Video on YouTube
    Refactoring to a System of Systems
    Video on YouTube

    View Slide

  41. Thank you!
    45
    Oliver Drotbohm ƀ [email protected]
    / odrotbohm

    View Slide