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

Growing Hexagonal Microservices by TDD

Growing Hexagonal Microservices by TDD

As Simon Brown says: “If you can’t build a well-structured monolith, what makes you think microservices is the answer?”
Hexagonal architecture is a model for designing extensible, modular software applications. The idea behind it is to isolate the domain of your application from outside concerns. If hexagonal architecture is structured properly, YAGNI principle can shape our scale needs and microservices born from well-crafted monoliths easier than ever.

A developer produces considerable amount of spaghetti/lasagna code and technical debt throughout her/his career. Hexagonal architecture lets developers focus on separation of concerns, therefore leads to maintainable and extensible codebase. It can also be called as Beyti code (Beyti is a Turkish-based well-known kebab type), named due to similarities with isolation layers, the core inside and repetitive structures.

Even though hexagonal architecture is somewhat easy to understand, building it well-crafted is a hard skill. Let us show how we grow hexagonal microservices from monoliths by using TDD. We will cover the following inter-related topics as well.

* TDD touching consumer driver contract tests, unit tests, dockerized integration tests.
* Evolution of a codebase, from a modular monolith to well-crafted microservices.
* Why mono repository is important for building hexagonal microservices and what are the cures to main headaches of mono repository.

Note: These are the slides I and Alican Akkuş presented at Java Day Istanbul 2020.

Lemi Orhan Ergin

September 12, 2020
Tweet

More Decks by Lemi Orhan Ergin

Other Decks in Technology

Transcript

  1. lemi orhan ergin
    co-founder,
    HEXAGONAL
    MICROSERVICES
    GROWING
    with tdd
    ali can akkuş
    software crafter,

    View Slide

  2. lemi orhan ergin
    co-founder,
    ali can akkuş
    software crafter,
    developing products, Craftbase
    alumni, Sony, eBay, ACM, iyzico
    founder, Software Craftsmanship Turkey
    programming, since 2001 with love
    speakerdeck.com/lemiorhan
    @lemiorhan
    developing products, Craftbase
    alumni, 32bit, iyzico
    practitioner, extreme programming
    jvm stack, java, groovy, spring
    alicanakkus.github.io
    @Alican_Akkus

    View Slide

  3. Layered architecture
    Web
    Domain
    Persistence
    From a certain layer, we can
    only access components in the
    same layer or in a layer below.
    LAYERS OF Isolation

    View Slide

  4. Web
    Domain
    Persistence CONSIDERED
    HARMFUL
    Layered architecture

    View Slide

  5. Application

    View Slide

  6. No way to understand what the code is about
    Domain logic is sca!ered throughout the layers
    Hard to understand where domain logic is
    Layers encourage horizontal coupling
    DDD do not work on partitioned architecture
    Many uncategorized components
    Application

    View Slide

  7. Your architectures should tell readers about the system,
    not about the frameworks you used in your system.
    SCREAMING ARCHITECTURE
    https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html
    Screaming Architecture, Robert C. Martin
    Application

    View Slide

  8. Web
    Domain
    Persistence
    Architecture sinkhole anti-pa!ern
    The fast lane reader anti-pa!ern
    You have to be self-disciplined
    Domain logic sca!ered throughout the layers
    Database/state drives the design
    Uncategorized helper and utility classes
    Monolith in nature
    Changing existing code instead of adding new
    Hard to change over time
    When it grows, it’s hard to test
    Open for hacking your own code
    Documentation is critical
    The Inconvenient truth

    View Slide

  9. Robert C. Martin
    Author of Clean Code and Clean Coder
    Owner of cleancoders.com training site
    The very first value of
    so"ware is to tolerate and
    facilitate on-going changes

    View Slide

  10. Make future changes easy
    No chain reaction of modification
    Big impact with few changes
    No workarounds or “just once” hacks
    Avoid accidental complexity
    Easy testing and verification
    MAINTAINABILITY
    The very first value of so"ware is to tolerate and facilitate on-going changes

    View Slide

  11. Immune to technical evolution
    Easy to add new integrations
    Delay technological decisions
    Testability in isolation
    Framework independent domain
    FLEXIBILITY
    The very first value of so"ware is to tolerate and facilitate on-going changes

    View Slide

  12. A timeless goal of so"ware engineering
    has been to separate code that changes
    frequently from code that is stable.
    James Coplien
    Quote from his „Lean Architecture‰ book

    View Slide

  13. A timeless goal of so"ware engineering has been to separate code that
    changes frequently from code that is stable.
    DOMAIN INFRASTRUCTURE
    Business logic
    Constraints and Behaviors
    What we really care about
    Integrations with infra components
    Technology and framework dependent
    How we make domain work

    View Slide

  14. A timeless goal of so"ware engineering has been to separate code that
    changes frequently from code that is stable.
    DOMAIN INFRASTRUCTURE
    Heart of the so!ware The detail

    View Slide

  15. Image Credit: Benoit Hediard, https://medium.com/@benorama/
    the-evolution-of-software-architecture-bd6ea674c477

    View Slide

  16. Credit: https://twitter.com/lemiorhan/status/1077894094402277376
    Image Credit: Benoit Hediard, https://medium.com/@benorama/
    the-evolution-of-software-architecture-bd6ea674c477

    View Slide

  17. domain
    HEXAGONAL
    ARCHITECTURE
    IN A NUTSHELL

    View Slide

  18. domain
    inside
    outside

    View Slide

  19. infra
    domain
    main
    component
    framework layer
    running at startup
    and builds the
    whole system
    technology agnostic
    core of application
    contains constraints
    and behaviors of the
    domain
    technology dependent
    layer that interacts
    with external devices
    via integration points

    View Slide

  20. infra
    domain
    Dependencies
    are from outside
    to inside

    View Slide

  21. infra
    domain
    interface
    implementation
    use
    implement

    View Slide

  22. infra
    domain
    port
    adapter
    use
    implement
    PORTS AND
    ADAPTERS

    View Slide

  23. user service
    repository
    adapter
    user service
    repository
    port
    DEPENDENCY INVERSION
    abstractions should not depend on details
    details should depend on abstractions
    high-level modules should not depend on low-level modules
    both should depend on abstractions
    LOW LEVEL MODULE
    DEPENDENCY
    INVERTED
    DEPENDENCY
    DIRECTED
    HIGH LEVEL MODULE

    View Slide

  24. infra
    domain
    rest
    api
    web
    ui
    3rd party apps
    command line
    soap calls
    admin gui
    batch jobs
    mobile apps
    other hexagons
    THE LEFT SIDE
    we find the actors who
    drive the domain
    adapts requests from the
    outside to our domain
    user side, primary adapters

    View Slide

  25. infra
    domain
    adapter
    use
    facade
    THE LEFT SIDE
    we find the actors who
    drive the domain
    adapts requests from the
    outside to our domain
    user side, primary adapters

    View Slide

  26. infra
    domain
    mysql
    adapter
    stripe
    adapter
    cache provider
    elastic search
    mail server
    database
    sms provider
    message queue
    other hexagons
    THE RIGHT SIDE
    integrations with the
    components that the
    application interacts with
    functionality needed
    by the application for
    implementing the
    business logic
    framework side, secondary
    adapters

    View Slide

  27. infra
    domain
    port
    adapter
    use
    implement
    THE RIGHT SIDE
    integrations with the
    components that the
    application interacts with
    functionality needed
    by the application for
    implementing the
    business logic
    framework side, secondary
    adapters

    View Slide

  28. infra
    domain
    mysql
    adapter
    stripe
    adapter
    rest
    api
    web
    ui

    View Slide

  29. infra
    domain
    stripe
    adapter
    rest
    api
    mysql
    adapter
    web
    ui
    billing search

    View Slide

  30. infra
    stripe
    adapter
    rest
    api
    mysql
    adapter
    web
    ui
    domain
    notification
    payment
    order
    basket
    restaurant
    scheduling
    caching
    mail
    account
    messaging
    billing search

    View Slide

  31. Packages by Features
    and Well-Defined Bounded Contexts

    View Slide

  32. infra
    domain
    WHEN & HOW
    TO WRITE
    TESTS

    View Slide

  33. infra
    domain
    adapter
    use
    facade
    model
    use
    dto
    use

    View Slide

  34. infra
    domain
    adapter
    use
    facade
    mock
    CONTRACT
    TESTS
    test
    facade
    dto
    use
    model
    use
    OUTSIDE-IN TDD

    View Slide

  35. io.craftbase.orderapi
    io.craftbase.orderapi
    CONTRACT TESTS

    View Slide

  36. domain
    facade
    port
    use
    use
    model
    use
    business
    logic
    use

    View Slide

  37. domain
    facade
    use
    use
    model
    use
    business
    logic
    use port
    mock
    TEST DRIVEN DEVELOPMENT
    main sub-product is unit tests
    test
    INSIDE-OUT TDD

    View Slide

  38. io.craftbase.orderapi
    io.craftbase.orderapi
    UNIT TESTS

    View Slide

  39. infra
    domain
    adapter
    implement
    port
    use
    use
    model
    entity
    use
    email
    client

    View Slide

  40. infra
    domain
    adapter
    implement
    port
    use
    use
    model
    entity
    use
    email
    client
    test
    FUNCTIONAL AND
    INTEGRATION TESTS
    tdd generates unit tests in addition to it
    mock
    client
    fake
    with
    wiremock

    View Slide

  41. io.craftbase.orderapi
    io.craftbase.orderapi
    UNIT TESTS

    View Slide

  42. io.craftbase.orderapi
    io.craftbase.orderapi
    INTEGRATION TESTS
    FOR ADAPTERS

    View Slide

  43. io.craftbase.orderapi
    io.craftbase.orderapi
    INTEGRATION TESTS
    FOR CONTROLLERS

    View Slide

  44. io.craftbase.orderapi
    io.craftbase.orderapi
    FUNCTIONAL TESTS
    VIA CUCUMBER

    View Slide

  45. TEST TYPES AT HEXAGONALS
    Domain
    Infra
    Unit Tests
    Unit Tests
    Integration Tests
    Component Tests
    Contract Tests
    External Verifier Stub Tests
    Functional Tests
    io.craftbase.orderapi
    io.craftbase.orderapi

    View Slide

  46. Evolution
    starts from
    big ball
    of mud, i.e.
    traditional
    monoliths

    View Slide

  47. infra
    stripe
    adapter
    rest
    api
    mysql
    adapter
    web
    ui
    domain
    ... to
    modular
    monoliths

    View Slide

  48. SEARCH
    ... and
    evolution
    continues
    with
    emerging
    micro
    services

    View Slide

  49. SEARCH
    PAYMENT
    ... and
    evolution
    continues
    with
    emerging
    micro
    services
    ... from
    modular
    monoliths

    View Slide

  50. SEARCH
    PAYMENT
    ACCOUNT
    ... and
    evolution
    continues
    with
    emerging
    micro
    services
    ... from
    modular
    monoliths

    View Slide

  51. SEARCH
    PAYMENT
    ACCOUNT
    ... and
    evolution
    continues
    with
    emerging
    micro
    services
    ... from
    modular
    monoliths

    View Slide

  52. how you go is always as important as
    where you go

    View Slide

  53. how you go is always as important as where you go
    @lemiorhan
    LEMi ORHAN ERGiN
    @alican_akkus ALİ CAN AKKUŞ

    View Slide