Ditch Your Framework
Kyle Boon
whoami
Engineering is about evaluating tradeoffs.
What is a framework?
A simpler definiton
History of HTTP Framework
Common Features
- Configuration
- Execution Model
- Dependency Injection
- Metrics
- Plugins
- Testing
- HTML Templating
- Persistence
- Session Management
- Authentication and Authorization
Frameworks like Spring are optimized for HTTP based CRUD applications
What about dependency injection?
Pure DI vs DI Container
// no container
class Engine() { }
class Car(val e: Engine) { }
val engine = Engine()
val car = Car(engine)
// using a container
val injector = Injector()
injector.register(Engine)
injector.register(Car)
val car = injector.getInstance(Car)
Downfalls of dependency injection
- Obfuscates the lifecycle of objects
- A main source of memory leaks
- Ever tried to make a request scoped object?
- For small applications, the utility of the DI container is usually not justified
Performance
What's the alternative?
Frameworks are to libraries as inheritance is to composition
Composing an Application
The bakeoff
- Select candidates
- Determine judging criteria
- Performance
- Testability
- Implement each candidate
- Discuss as a group
- Determine the winner
- Make an Architectural Decision Record
Compass/Radar Chart
My Team's Champions
Library | Use |
---|---|
OkHTTP | HTTP Client |
HTTP4k + undertow | HTTP server |
Jackson | json parsing |
lightbent/config | configuration |
LMAX Disrupter + native kafka client | kafka consumption and production |
micrometer | metrics |
RocksDB | persistence |
kotest + junit | testing |
main()
The main method becomes the composition root.
This is usually the longest bit of code in your application, it's where you instantiate objects and start threadpools.
Some Tips
- Single method interfaces are you friends
- Only pass these interfaces between objects you create
- The main() method will reveal all of your applications dependencies
- As you build multiple applications, refactor common patterns to new libraries
markdown-loader | 567 |
markdown-transformer | 831 |
item-location-reducer | 3151 |
delivery-schedule-loader | 1199 |
spu-transformer | 674 |
item-node-relationship-transformer | 886 |
item-node-topology-transformer | 1473 |
end-of-season-transformer | 648 |
optimizer-wrapper | 5739 |
delivery-schedule-transformer | 675 |
policy-transformer | 3520 |
transfer-pack-loader | 1383 |
item-network-reducer | 3784 |
air-forecast-loader | 395 |
lead-time-transformer | 2094 |
item-node-topology-loader | 1382 |
sellable-item-arc-transformer | 1223 |
end-of-season-loader | 980 |
lead-time-loader | 1672 |
frontloading-transformer | 834 |
end-of-season-kafka-transformer | 609 |
item-node-relationship-loader | 998 |
demand-curve-coverage-transformer | 747 |
transfer-pack-transformer | 627 |
frontloading-loader | 460 |
end-of-season-kafka-loader | 401 |
demand-curve-coverage-loader | 1040 |
air-forecast-transformer | 2809 |
spu-loader | 412 |
commons | 2056 |
config | 199 |
http4k | 1987 |
kafka | 6124 |
metrics | 393 |
storage | 1426 |
test-commons | 841 |
test-kafka | 807 |
How Much Code Is It?