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.

Dafc4723e9a1c067796c0fec6f509774?s=128

Lemi Orhan Ergin

September 12, 2020
Tweet

Transcript

  1. lemi orhan ergin co-founder, HEXAGONAL MICROSERVICES GROWING with tdd ali

    can akkuş software crafter,
  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
  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
  4. Web Domain Persistence CONSIDERED HARMFUL Layered architecture

  5. Application

  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
  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
  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
  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
  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
  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
  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
  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
  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
  15. Image Credit: Benoit Hediard, https://medium.com/@benorama/ the-evolution-of-software-architecture-bd6ea674c477

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

  17. domain HEXAGONAL ARCHITECTURE IN A NUTSHELL

  18. domain inside outside

  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
  20. infra domain Dependencies are from outside to inside

  21. infra domain interface implementation use implement

  22. infra domain port adapter use implement PORTS AND ADAPTERS

  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
  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
  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
  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
  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
  28. infra domain mysql adapter stripe adapter rest api web ui

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

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

    notification payment order basket restaurant scheduling caching mail account messaging billing search
  31. Packages by Features and Well-Defined Bounded Contexts

  32. infra domain WHEN & HOW TO WRITE TESTS

  33. infra domain adapter use facade model use dto use

  34. infra domain adapter use facade mock CONTRACT TESTS test facade

    dto use model use OUTSIDE-IN TDD
  35. io.craftbase.orderapi io.craftbase.orderapi CONTRACT TESTS

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

  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
  38. io.craftbase.orderapi io.craftbase.orderapi UNIT TESTS

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

    email client
  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
  41. io.craftbase.orderapi io.craftbase.orderapi UNIT TESTS

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

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

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

  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
  46. Evolution starts from big ball of mud, i.e. traditional monoliths

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

    ... to modular monoliths
  48. SEARCH ... and evolution continues with emerging micro services

  49. SEARCH PAYMENT ... and evolution continues with emerging micro services

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

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

    services ... from modular monoliths
  52. how you go is always as important as where you

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

    go @lemiorhan LEMi ORHAN ERGiN @alican_akkus ALİ CAN AKKUŞ