SlideShare a Scribd company logo
Lucas Cavalcanti

@lucascs
Microservices in
Clojure
Context
Microservices
~80 Clojure services
~60 engineers
~10 teams
3.5 years old
OOP
Objects, the mainstream abstraction
Image @ http://www.eduardopires.net.br/2015/01/solid-teoria-e-pratica/
What about Functional Programming?
SÃO PAULO, BRASIL
TABLE OF CONTENTS
Immutability
Components
Pure Functions
Schemas
Ports and Adapters
SÃO PAULO, BRASIL
Immutability
SOUTHEAST BRAZIL REGION FROM SPACE
Immutability
Definition
“If I’m given a value, it’s guaranteed that it won’t ever change”
Technology choices
Immutability
Clojure
Immutability
All default data structures are immutable:
-Maps, Lists, Sets
-Records
Mutability is explicit: atoms/refs @, dynamic vars *…*
Datomic
Immutability
Datomic stores the changes/transactions, not just the
data
-append only
-db as a value
-everything is data (transaction, schema, entities)
Kafka
Immutability
Persistent Queues/Topics
-each consumer has its offset
-ability to replay messages
AWS + Docker
Immutability
Ability to spin machines with a given image/
configuration
-Each build generates a docker image
-Each deploy spins a new machine with the new
version
-As soon as the new version is healthy, old version is
killed. (blue-green deployment)
Components
SOUTHEAST BRAZIL REGION FROM SPACE
Components
https://github.com/stuartsierra/component
(defprotocol Database

(query [this query-str]))



(defrecord SomeDatabase [config-1 config-2 other-components]

component/Lifecycle

(start [this]

(assoc this :connection (connect! config-1 config-2 other-components)))



(stop [this]

(release! (:connection this))

(dissoc this :connection))



Database

(query [this query-str] (do-query! (:connection this) query-str)))
System map
Components
{:database #SomeDatabase{...}

:http-client #HttpClient{...}

:kafka #Kafka{...}

:auth #AuthCredentials{...}

...}
-Created at startup
-Entrypoints (e.g http server or kafka consumers) have access to all
components the business flows need
-dependencies of a given flow are threaded from the entry point until
the end, one by one if possible
-Thus no static access to system map! (e.g via a global atom)
-Any resemblance to objects and classes is just coincidence ;)
Pure functions
SOUTHEAST BRAZIL REGION FROM SPACE
Pure functions
Definition
"Given the same inputs, it will always produce the same output"
Simplicity
Pure functions
-easier to reason about, fewer moving pieces
-easier to test, less need for mocking values
-parallelizable by default, no need for locks or STMs
Datomic
Pure functions
-Datomic’s db as a value allows us to consider a function
that queries the database as a pure function
-db is a snapshot of the database at a certain point in time.
-So, querying the same db instance will always produce the
same result
Impure functions
Pure functions
-functions that produce side effects should be marked as
such. We use `!` at the end.
-split code which handles and transforms data from code
that handles side effects
-should be moved to the borders of the flow, if possible
-Consider returning a future/promise like value, so side
effect results can be composed (e.g with manifold or
finagle)
https://github.com/ztellman/manifold
https://github.com/twitter/finagle
Schema/Spec
SOUTHEAST BRAZIL REGION FROM SPACE
Schema
Legacy
Majority of our code base was written before clojure.spec existed,
so I’ll be talking about the Schema library instead. Most principles
apply to clojure.spec as well.
Schema/Spec
Documentation
-Clojure doesn’t force you to write types
-parameter names are not enough
-declaring types helps a lot when glancing at the function
-values can be verified against a schema
Function declaration
Schema/spec
-All pure functions declare schemas for parameters and
return value
-All impure functions declare for parameters and don’t
declare output type if it’s not relevant.
-Validated at runtime in dev/test environments, on every
function call
-Validation is off on production.
Wire formats
Schema/Spec
-Internal schemas are your domain models
-Wire schemas are how you expose data to other services/
clients
-If they are different, you can evolve internal schemas
without breaking clients
-Need an adapter layer
-wire schemas are always validated on entry/exit points,
specially in production
-single repository for all wire schemas (for all 60+ services)
-caveat: this repository has a really high churn. Beware
Growing Schemas
Spec-ulation
Please watch Rich Hickey’s talk at Clojure Conj 2016
Spec-ulation:
https://www.youtube.com/watch?v=oyLBGkS5ICk
Ports and Adapters
(a.k.a Hexagonal Architecture)
SOUTHEAST BRAZIL REGION FROM SPACE
Ports and Adapters
Definition
Core logic is independent to how we can call it (yellow)
A port is an entry-point of the application (blue)
An adapter is the bridge between a port and the core logic (red)
http://www.dossier-andreas.net/software_architecture/ports_and_adapters.html
http://alistair.cockburn.us/Hexagonal+architecture
Ports and Adapters (Nubank version)
Extended Definition
Pure business logic (green)
Controller logic wires the flow between the ports (yellow)
A port is an entry-point of the application (blue)
An adapter is the bridge between a port and the core logic (red)
Ports (Components)
Ports and Adapters
-Ports are initialised at startup
-Each port has a corresponding
component
-Serializes data to a transport
format (e.g JSON, Transit)
-Usually library code shared by
all services
-Tested via integration tests
HTTP
Kafka
Datomic
File Storage
Metrics
E-mail
Adapters (Diplomat)
Ports and Adapters
-Adapters are the interface to
ports
-Contain HTTP and Kafka
consumer handlers
-Adapt wire schema to
internal schema
-Calls and is called by
controller functions
-Tested with fake versions of
the port components, or
mocks
HTTP
Kafka
Datomic
File Storage
Metrics
E-mail
Controllers
Ports and Adapters
-Controllers wires the flow
between entry-point and the
side effects
-Only deals with internal
schemas
-Delegates business logic to
pure functions
-Composes side effect results
-Tested mostly with mocks
HTTP
Kafka
Datomic
File Storage
Metrics
E-mail
Business Logic
Ports and Adapters
-Handles and transforms
immutable data
-Pure functions
-Best place to enforce
invariants and type checks
(e.g using clojure.spec)
-Can be tested using
generative testing
-Should be the largest part of
the application
HTTP
Kafka
Datomic
File Storage
Metrics
E-mail
Microservices
Ports and Adapters
-Each service follows about
the same design
-Services communicate with
each other using one of the
ports (e.g HTTP or Kafka)
-Services DON’T share
databases
-HTTP responses contain
hypermedia, so we can
replace a service without
having to change clients
-Tested with end to end tests,
with all services deployed
Clojure is simple
Keep your design simple
Keep your architecture simple
SÃO PAULO, BRASIL
Lucas Cavalcanti

@lucascs
Thank you

More Related Content

PDF
Grokking TechTalk #33: High Concurrency Architecture at TIKI
PDF
Evolution of MySQL Parallel Replication
PDF
All about InfluxDB.
PDF
Build an Edge-to-Cloud Solution with the MING Stack
PDF
Influxdb and time series data
PPT
Fundamentos de SDN (Software Defined Networking)
PDF
Tuning Autovacuum in Postgresql
PDF
Ceph and RocksDB
Grokking TechTalk #33: High Concurrency Architecture at TIKI
Evolution of MySQL Parallel Replication
All about InfluxDB.
Build an Edge-to-Cloud Solution with the MING Stack
Influxdb and time series data
Fundamentos de SDN (Software Defined Networking)
Tuning Autovacuum in Postgresql
Ceph and RocksDB

What's hot (20)

ODP
OpenGurukul : Database : PostgreSQL
PDF
E-Commerce search with Elasticsearch
PDF
Time Series Data with InfluxDB
PDF
Intro to Elasticsearch
PDF
Splunk Application logging Best Practices
PDF
Local DNS with pfSense 2.4 - pfSense Hangout April 2018
PPTX
MarcEdit Shelter-In-Place Webinar 8: Automated editing through scripts and to...
PDF
The Dual write problem
PDF
Dense Retrieval with Apache Solr Neural Search.pdf
ODP
Deep Dive Into Elasticsearch
PDF
Elasticsearch
PDF
Zero Data Loss Recovery Applianceによるデータベース保護のアーキテクチャ
PDF
OpenNebulaConf2018 - Scalable L2 overlay networks with routed VXLAN / BGP EVP...
PPTX
NLP techniques for log analysis
PDF
MPLS MPLS Inter-AS MPLS CSC
PPTX
Analyzing 1.2 Million Network Packets per Second in Real-time
PDF
MySQL GTID Concepts, Implementation and troubleshooting
PDF
Presto: Optimizing Performance of SQL-on-Anything Engine
PDF
ElasticSearch
PDF
MariaDB 10.11 key features overview for DBAs
OpenGurukul : Database : PostgreSQL
E-Commerce search with Elasticsearch
Time Series Data with InfluxDB
Intro to Elasticsearch
Splunk Application logging Best Practices
Local DNS with pfSense 2.4 - pfSense Hangout April 2018
MarcEdit Shelter-In-Place Webinar 8: Automated editing through scripts and to...
The Dual write problem
Dense Retrieval with Apache Solr Neural Search.pdf
Deep Dive Into Elasticsearch
Elasticsearch
Zero Data Loss Recovery Applianceによるデータベース保護のアーキテクチャ
OpenNebulaConf2018 - Scalable L2 overlay networks with routed VXLAN / BGP EVP...
NLP techniques for log analysis
MPLS MPLS Inter-AS MPLS CSC
Analyzing 1.2 Million Network Packets per Second in Real-time
MySQL GTID Concepts, Implementation and troubleshooting
Presto: Optimizing Performance of SQL-on-Anything Engine
ElasticSearch
MariaDB 10.11 key features overview for DBAs
Ad

Similar to Microservices in Clojure (20)

PDF
The productivity brought by Clojure
PDF
Functional web with clojure
PDF
Complex made bearable Clojure conj 2019
PDF
FleetDB A Schema-Free Database in Clojure
PDF
FleetDB: A Schema-Free Database in Clojure
PPTX
Clojure Fundamentals Course For Beginners
ODP
Getting started with Clojure
PDF
FP Days: Down the Clojure Rabbit Hole
PDF
I know Java, why should I consider Clojure?
PDF
Clojure for Java developers
PDF
The never changing face of immutability
PDF
Clojure, Plain and Simple
PDF
Introduction to Clojure
PDF
Thinking Functionally with Clojure
PDF
Thinking Functionally - John Stevenson - Codemotion Rome 2017
PDF
A Java Developers first Clojure project
PDF
Full Stack Clojure
PDF
Clojutre Real Life (2012 ClojuTRE Retro Edition)
PDF
Clojure and The Robot Apocalypse
PDF
Introductory Clojure Presentation
The productivity brought by Clojure
Functional web with clojure
Complex made bearable Clojure conj 2019
FleetDB A Schema-Free Database in Clojure
FleetDB: A Schema-Free Database in Clojure
Clojure Fundamentals Course For Beginners
Getting started with Clojure
FP Days: Down the Clojure Rabbit Hole
I know Java, why should I consider Clojure?
Clojure for Java developers
The never changing face of immutability
Clojure, Plain and Simple
Introduction to Clojure
Thinking Functionally with Clojure
Thinking Functionally - John Stevenson - Codemotion Rome 2017
A Java Developers first Clojure project
Full Stack Clojure
Clojutre Real Life (2012 ClojuTRE Retro Edition)
Clojure and The Robot Apocalypse
Introductory Clojure Presentation
Ad

More from Lucas Cavalcanti dos Santos (6)

PDF
Arquitetando uma instituição financeira moderna
PDF
Arquitetura funcional em microservices, 4 anos depois
PDF
Building a powerful double entry accounting system
PPTX
Testando a integracao entre serviços - Agile Brazil 2014
PPTX
O poder da linguagem Ruby e as suas consequências
ODP
Otimizacao prematura-agile-brazil-12
Arquitetando uma instituição financeira moderna
Arquitetura funcional em microservices, 4 anos depois
Building a powerful double entry accounting system
Testando a integracao entre serviços - Agile Brazil 2014
O poder da linguagem Ruby e as suas consequências
Otimizacao prematura-agile-brazil-12

Recently uploaded (20)

PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Digital Strategies for Manufacturing Companies
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
System and Network Administraation Chapter 3
PDF
AI in Product Development-omnex systems
PDF
Nekopoi APK 2025 free lastest update
PPTX
L1 - Introduction to python Backend.pptx
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
ai tools demonstartion for schools and inter college
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
Transform Your Business with a Software ERP System
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
Odoo Companies in India – Driving Business Transformation.pdf
How to Migrate SBCGlobal Email to Yahoo Easily
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
2025 Textile ERP Trends: SAP, Odoo & Oracle
Digital Strategies for Manufacturing Companies
Internet Downloader Manager (IDM) Crack 6.42 Build 41
System and Network Administraation Chapter 3
AI in Product Development-omnex systems
Nekopoi APK 2025 free lastest update
L1 - Introduction to python Backend.pptx
VVF-Customer-Presentation2025-Ver1.9.pptx
ai tools demonstartion for schools and inter college
Navsoft: AI-Powered Business Solutions & Custom Software Development
Which alternative to Crystal Reports is best for small or large businesses.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
CHAPTER 2 - PM Management and IT Context
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Transform Your Business with a Software ERP System
Upgrade and Innovation Strategies for SAP ERP Customers

Microservices in Clojure

  • 2. Context Microservices ~80 Clojure services ~60 engineers ~10 teams 3.5 years old
  • 3. OOP Objects, the mainstream abstraction Image @ http://www.eduardopires.net.br/2015/01/solid-teoria-e-pratica/
  • 4. What about Functional Programming? SÃO PAULO, BRASIL
  • 5. TABLE OF CONTENTS Immutability Components Pure Functions Schemas Ports and Adapters SÃO PAULO, BRASIL
  • 7. Immutability Definition “If I’m given a value, it’s guaranteed that it won’t ever change”
  • 9. Clojure Immutability All default data structures are immutable: -Maps, Lists, Sets -Records Mutability is explicit: atoms/refs @, dynamic vars *…*
  • 10. Datomic Immutability Datomic stores the changes/transactions, not just the data -append only -db as a value -everything is data (transaction, schema, entities)
  • 11. Kafka Immutability Persistent Queues/Topics -each consumer has its offset -ability to replay messages
  • 12. AWS + Docker Immutability Ability to spin machines with a given image/ configuration -Each build generates a docker image -Each deploy spins a new machine with the new version -As soon as the new version is healthy, old version is killed. (blue-green deployment)
  • 14. Components https://github.com/stuartsierra/component (defprotocol Database
 (query [this query-str]))
 
 (defrecord SomeDatabase [config-1 config-2 other-components]
 component/Lifecycle
 (start [this]
 (assoc this :connection (connect! config-1 config-2 other-components)))
 
 (stop [this]
 (release! (:connection this))
 (dissoc this :connection))
 
 Database
 (query [this query-str] (do-query! (:connection this) query-str)))
  • 15. System map Components {:database #SomeDatabase{...}
 :http-client #HttpClient{...}
 :kafka #Kafka{...}
 :auth #AuthCredentials{...}
 ...} -Created at startup -Entrypoints (e.g http server or kafka consumers) have access to all components the business flows need -dependencies of a given flow are threaded from the entry point until the end, one by one if possible -Thus no static access to system map! (e.g via a global atom) -Any resemblance to objects and classes is just coincidence ;)
  • 16. Pure functions SOUTHEAST BRAZIL REGION FROM SPACE
  • 17. Pure functions Definition "Given the same inputs, it will always produce the same output"
  • 18. Simplicity Pure functions -easier to reason about, fewer moving pieces -easier to test, less need for mocking values -parallelizable by default, no need for locks or STMs
  • 19. Datomic Pure functions -Datomic’s db as a value allows us to consider a function that queries the database as a pure function -db is a snapshot of the database at a certain point in time. -So, querying the same db instance will always produce the same result
  • 20. Impure functions Pure functions -functions that produce side effects should be marked as such. We use `!` at the end. -split code which handles and transforms data from code that handles side effects -should be moved to the borders of the flow, if possible -Consider returning a future/promise like value, so side effect results can be composed (e.g with manifold or finagle) https://github.com/ztellman/manifold https://github.com/twitter/finagle
  • 22. Schema Legacy Majority of our code base was written before clojure.spec existed, so I’ll be talking about the Schema library instead. Most principles apply to clojure.spec as well.
  • 23. Schema/Spec Documentation -Clojure doesn’t force you to write types -parameter names are not enough -declaring types helps a lot when glancing at the function -values can be verified against a schema
  • 24. Function declaration Schema/spec -All pure functions declare schemas for parameters and return value -All impure functions declare for parameters and don’t declare output type if it’s not relevant. -Validated at runtime in dev/test environments, on every function call -Validation is off on production.
  • 25. Wire formats Schema/Spec -Internal schemas are your domain models -Wire schemas are how you expose data to other services/ clients -If they are different, you can evolve internal schemas without breaking clients -Need an adapter layer -wire schemas are always validated on entry/exit points, specially in production -single repository for all wire schemas (for all 60+ services) -caveat: this repository has a really high churn. Beware
  • 26. Growing Schemas Spec-ulation Please watch Rich Hickey’s talk at Clojure Conj 2016 Spec-ulation: https://www.youtube.com/watch?v=oyLBGkS5ICk
  • 27. Ports and Adapters (a.k.a Hexagonal Architecture) SOUTHEAST BRAZIL REGION FROM SPACE
  • 28. Ports and Adapters Definition Core logic is independent to how we can call it (yellow) A port is an entry-point of the application (blue) An adapter is the bridge between a port and the core logic (red) http://www.dossier-andreas.net/software_architecture/ports_and_adapters.html http://alistair.cockburn.us/Hexagonal+architecture
  • 29. Ports and Adapters (Nubank version) Extended Definition Pure business logic (green) Controller logic wires the flow between the ports (yellow) A port is an entry-point of the application (blue) An adapter is the bridge between a port and the core logic (red)
  • 30. Ports (Components) Ports and Adapters -Ports are initialised at startup -Each port has a corresponding component -Serializes data to a transport format (e.g JSON, Transit) -Usually library code shared by all services -Tested via integration tests HTTP Kafka Datomic File Storage Metrics E-mail
  • 31. Adapters (Diplomat) Ports and Adapters -Adapters are the interface to ports -Contain HTTP and Kafka consumer handlers -Adapt wire schema to internal schema -Calls and is called by controller functions -Tested with fake versions of the port components, or mocks HTTP Kafka Datomic File Storage Metrics E-mail
  • 32. Controllers Ports and Adapters -Controllers wires the flow between entry-point and the side effects -Only deals with internal schemas -Delegates business logic to pure functions -Composes side effect results -Tested mostly with mocks HTTP Kafka Datomic File Storage Metrics E-mail
  • 33. Business Logic Ports and Adapters -Handles and transforms immutable data -Pure functions -Best place to enforce invariants and type checks (e.g using clojure.spec) -Can be tested using generative testing -Should be the largest part of the application HTTP Kafka Datomic File Storage Metrics E-mail
  • 34. Microservices Ports and Adapters -Each service follows about the same design -Services communicate with each other using one of the ports (e.g HTTP or Kafka) -Services DON’T share databases -HTTP responses contain hypermedia, so we can replace a service without having to change clients -Tested with end to end tests, with all services deployed
  • 35. Clojure is simple Keep your design simple Keep your architecture simple SÃO PAULO, BRASIL