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

Slides of the talk I gave at Spring I/O, 2019 in Barcelona.

Oliver Drotbohm

May 16, 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. The Sample Codebase
    6

    View Slide

  7. 7
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  11. 11
    package com.acme
    @Modulith // Instead of @SpringBootApplication
    class MyApplication { … }
    Applies package conventions

    View Slide

  12. Package structure
    DEMO
    12

    View Slide

  13. Moduliths
    13
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. 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

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

    View Slide

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

    View Slide

  16. 16
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  17. 17
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  18. Single module bootstrap
    DEMO
    18

    View Slide

  19. 19
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  20. 20
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  21. 21
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    View Slide

  22. Detect and remove violation
    DEMO
    22

    View Slide

  23. 23
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    Event
    Event publication

    View Slide

  24. Dependency types
    24
    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.

    View Slide

  25. Dependency types
    25
    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

  26. 26
    Orders Business

    Time
    Catalog
    Inventory
    Component Dependency Type dependency

    Event
    Event publication

    View Slide

  27. Multi module bootstrap
    DEMO
    27

    View Slide

  28. Bootstrap modes
    28
    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

  29. Moduliths
    29
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. 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.
    3. Simple set of access rules and API to verify
    Only access components in module API packages.

    View Slide

  30. Some conventions…
    30
    01
    10
    M
    M
    01
    10 Allowed by the compiler
    Allowed by Moduliths
    Rejected by the compiler
    Rejected by Moduliths
    Public
    Package protected
    Bounded Context
    Java Package

    View Slide

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

    View Slide

  32. Module B
    moduleB
    Module A
    moduleA
    32
    ComponentA
    ComponentAImpl
    ComponentB
    ComponentBImpl
    Public Package protected
    Bounded Context Java Package
    01
    10
    01
    10

    View Slide

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

    View Slide

  34. API Package Convention
    34
    ….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

  35. Module A
    moduleA.foo
    Module B
    moduleB
    moduleA
    35
    ComponentA
    ComponentAImpl
    ComponentB
    ComponentBImpl
    moduleA.bar
    SupportA
    SupportAImpl
    01
    10 M
    01
    10
    01
    10
    Public
    Package protected
    Bounded Context
    Java Package

    View Slide

  36. Violation detection
    Module cycles / Internal components
    DEMO
    36

    View Slide

  37. Moduliths
    37
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. 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.
    3. Simple set of access rules and API to verify
    Only access components in module API packages.
    4. Documentation support
    PlantUML integration via Simon Brown’s Structurizr to
    document module structure and dependency types.

    View Slide

  38. Documentation
    DEMO
    38

    View Slide

  39. Tool ecosystem and
    alternative approaches
    39

    View Slide

  40. Multiple Artifacts
    40
    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

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

    View Slide

  42. External Tools
    42
    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

  43. Moduliths
    43
    1. A convention to map contexts to packages
    Packages directly nested underneath the main application
    package are considered context ones.
    2. 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.
    3. Simple set of access rules and API to verify
    Only access components in module API packages.
    4. Documentation support
    PlantUML integration via Simon Brown’s Structurizr to
    document module structure and dependency types.

    View Slide

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

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

    View Slide