Are you tired of baby examples for Kotlin (or any programming language, platform, framework or library)?
In this talk, we’re going to explore how are real, and large applications are built.
These are the practices that worked well for countless product teams.
What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
1. What Are The Best Practices
When Building a Back-end App
With Kotlin And Spring Boot?
by Oleksii Fedorov
bit.ly/k-boot-slides
1
2. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Who am I?
Oleksii Fedorov
• Sr Software Engineer @ Pivotal Berlin
• Entrepreneur In-house @ Pivotal Berlin
• Founder @ iwillteachyoukotlin.com
• Kotlin on Back-end in Production for 2+ years
• Programming for more than 2/3 of my life
• Writer, mentor, coach
• @waterlink000 on Twitter
bit.ly/k-boot-slides
2
3. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
3
4. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Process Overview
User Story
Acceptance
Criteria
Write One
Top-level
Failing Test
Think a Little
About Design
Write Failing
Unit Test
Make Failing
Unit Test Pass
Refactor
Make Failing
Top-level Test
Pass
TDD Cycle
Outside-In
Cycle
bit.ly/k-boot-slides
4
5. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
User Story Example
The WHY
As a Developer on the team,
I need to understand the WHY behind the user story,
So that I know which parts are most important,
and can offer better and simpler solution alternatives.
The HOW
As a Developer on the team,
I need to have a well-written Acceptance Criteria,
So that I can write my top-level tests,
and be sure that them passing means I’m done,
and I can deploy.
bit.ly/k-boot-slides
5
6. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Acceptance Criteria Example
Acceptance Criteria
(from sign-up user story)
Given I have created the account with email “sali@example.org"
and name "Sali"
When I follow the link in the confirmation email
Then I see that my account has been successfully confirmed
And I see that I am logged in
bit.ly/k-boot-slides
6
7. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Developer’s Checklist Before
Starting The User Story (1/2)
Is the WHY behind the user story clear?
If not, ask 5+ WHY’s until it is clear, or proven that the user story
doesn’t have real user/customer value in it.
Does it agree with your understanding of the product vision?
If not, ask questions as to how the feature helps us achieve the
goals of the product.
(This way either user story needs to change, or your understanding of the vision)
Is it ethical by your personal standard?
If not, raise your concern. Start the conversation. Potentially,
refuse to work on it, if the user story doesn’t fit your ethics after
the conversation.
bit.ly/k-boot-slides
7
8. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Developer’s Checklist Before
Starting The User Story (2/2)
Does user story have proper Acceptance Criteria?
Does it cover all the interesting scenarios you can think of?
Is it too large? Can and should it be split?
Is the language of Acceptance Criteria more focused on UI? Will
the acceptance criteria need to be rewritten on every UI/UX
change?
If yes, make sure it talks more in the business domain language,
and in terms of user-system interaction. Simple UI/UX change
should not force you to rewrite all the Acceptance Criteria.
bit.ly/k-boot-slides
8
9. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Download This Checklist as PDF
bit.ly/dev-user-story-checklist
bit.ly/k-boot-slides
9
10. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• > Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
10
11. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Outside-In
1. Start with higher-level test, such as UI or Integration test.
2. Write only single test that is failing.
3. Apply Test-Driven Development to implement all the parts of the
system required just to make the current higher-level failing test
pass.
4. If not done with the feature yet, go back to 1.
bit.ly/k-boot-slides
11
12. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Example Feature Test
bit.ly/k-boot-slides
12
13. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Wha…? How?!
bit.ly/k-boot-slides
13
14. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Yep, they are just nouns that do
nothing. What about steps?
bit.ly/k-boot-slides
14
15. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
bit.ly/k-boot-slides
15
16. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
bit.ly/k-boot-slides
16
17. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Ah. UI tests.
Wouldn’t they break easily?
bit.ly/k-boot-slides
17
18. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Not easily if you use QA tags.
bit.ly/k-boot-slides
18
19. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• > Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
19
20. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Evolutionary Architecture
Short Story of Two Teams
• First team is using exactly the same architecture as the second
one:
• Controller calls Service object
• Service object calls other service objects and repository
objects
• Repository object talks to the database
• Now, the first team is absolutely unhappy:
• “OMG, I’m just passing through things like a dummy!”
• “Okay, there is nothing to write in this Service…”
• “Hold on, why do I need to add this field to three DTOs?!”
• And the second team is absolutely happy
bit.ly/k-boot-slides
20
21. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why?
bit.ly/k-boot-slides
21
22. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why? (1/2)
• The first team had a very simple business domain:
• Service layer practically did nothing, and was a pass-through to
the repository or a 3rd party API.
• There were only a few validations, and they were done at the
Controller level.
• Also, they had three DTOs for each concept for each of the
layers (presentation, business domain, and data storage).
What strikes as a odd thing is that they didn’t have different
structure.
• So most of the work was just passing through, and converting
from one DTO to another without actual value.
• It was painful.
bit.ly/k-boot-slides
22
23. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why? (2/2)
• The second team had a very complex business domain:
• Service layer was performing a lot of interesting logic. Often
you’ll see that service layer had 2-3 sub-layers, where more
complex services call out to simpler service objects.
• They had 3 DTOs for most of their concepts as well, but these
were actually different because they’ve dealt with the database
schema that they couldn’t control, and they had multiple clients
to which they had to present concepts in different structure.
• While that is much more work than the first team had to do, it is
actually work that has meaning and value to it.
• So they were happy!
bit.ly/k-boot-slides
23
24. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
All Good Architectures
Suffer From This Problem
• Clean Architecture
• Hexagonal Architecture
• Ports And Adapters
• MVC, MVVM, MVP
• DDD, Event-Sourcing and CQRS
bit.ly/k-boot-slides
24
25. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why?
bit.ly/k-boot-slides
25
26. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Max Domain Complexity
bit.ly/k-boot-slides
26
27. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Complexity Mismatch
Define any architecture, and it will have a sweet spot for the “ideal”
complexity that it can handle.
When the difference between the “ideal” complexity and the real
complexity is too high, developers and productivity will suffer,
either:
- from business domain exceeding the maximum complexity of the
architecture, and becoming a big ball of mud,
- or from business domain being too simple for the architecture,
and causing useless demotivating “make-work.”
bit.ly/k-boot-slides
27
28. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Solution?
bit.ly/k-boot-slides
28
29. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Crystal Ball And Ability
to See The Future
If only I had one…
bit.ly/k-boot-slides
29
30. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Make The Best Pragmatic Guess
And refactor once you know that you’ve made a mistake
You’ll need to go either up or down the scale of the cleanliness as
the codebase gives you more and more feedback
bit.ly/k-boot-slides
30
31. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
That is Exactly Why I Usually Start
Somewhere in The Middle
You’ll have less to refactor on average
bit.ly/k-boot-slides
31
32. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• > Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
32
33. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Controller-Service-Repository
(Light version)
QuizController QuizService QuizRepository
(called by Spring framework) (talks to JdbcTemplate, or is a
JPA/Hibernate)
(where your business logic
resides)
bit.ly/k-boot-slides
33
34. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Has only one DTO
QuizController QuizService QuizRepository
Quiz Quiz
Framework
Quiz
Database
Quiz
bit.ly/k-boot-slides
34
35. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
As You Accumulate Complexity
QuizController QuizService QuizRepository
Quiz
Framework
QuizViewModel
Database
QuizEntity
Introduce More DTOs
QuizEntity
35
36. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Or Introduce New Services
QuizController
QuizService QuizRepository
As You Accumulate Complexity
ImageService UploadsSaasProvider
ImageController
bit.ly/k-boot-slides
36
37. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
What if Your Domain is Simpler?
(Lighter Version)
QuizController QuizRepository
and put your simplest business
logic here
leave this as a simple data
storage layer
talk directly to
repository
In the simplest case, you
might use RestRepository
bit.ly/k-boot-slides
37
38. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Typical MVC Controller (1/4)
• Constructor dependency injection, so that it’s easier to test
• Depends only on one or two services
• If you need three and more, split controller into multiple ones
(CQRS might help here)
• Might depend on some framework things
bit.ly/k-boot-slides
38
39. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Typical MVC Controller (2/4)
• Simple GET methods that:
• prepare the view model, and
• render the appropriate template.
bit.ly/k-boot-slides
39
40. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Typical MVC Controller (3/4)
Authenticate
Authorise
And find data
Prepare view
model
Render view
More involved GET methods
No business logic!
40
41. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Typical MVC Controller (4/4)
Authenticate
Authorise
Ask business
domain code
to perform
action
Prepare &
render view
POST/PUT/etc (modifying) methods
No business logic!
Validate
41
42. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Unit-testing Typical Controller (1/3)
• Start by creating and configuring all the mocks you need
(typically, all your dependencies).
• As you TDD your way through this, you will add more mocks as
you go.
42
43. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Unit-testing Typical Controller (2/3)
• Create controller object, injecting dependencies manually via
constructor.
• Create “mockMvc” object that you’ll use to perform requests to
that controller.
bit.ly/k-boot-slides
43
44. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
I always forget how to create “mockMvc” properly
Solution: extract a helper function
bit.ly/k-boot-slides
44
45. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Unit-testing Typical Controller (3/3)
Setup world
Perform
Verify that
everything
works as
expected
You will have to mock away all service objects here
because of architectural boundary
45
46. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Don’t Create DTOs in Tests Directly
Have a smart factory method in
your test helpers with Kotlin’s
default and named parameters
And a few “standard” objects
46
47. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Join My Newsletter
• Early bird for screencast series:
“Kotlin/Back-End Best Practices.”
• Exclusive articles about Kotlin monthly.
bit.ly/kotlin-newsletter
bit.ly/k-boot-slides
47
48. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• > All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
48
49. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
All* Apps Are Just Glorified
CRUDs
*—most of them are (80%). And in the beginning of any product,
they all are CRUDs in some twisted sense of the word.
bit.ly/k-boot-slides
49
50. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
CRUD
• User can CREATE the resource
• User can READ the resource or multiple resources
• User can UPDATE the existing resource
• User can DELETE the existing resource
bit.ly/k-boot-slides
50
51. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Glorified CRUD
• User can CREATE the resource
• User can READ the resource or multiple resources
• User can UPDATE the existing resource
• User can DELETE the existing resource
• — PLUS —
• User can only UPDATE and DELETE resources they OWN
• User can READ some resources that they were given access to
• User can TRANSFER OWNERSHIP to the other user
• Users can COLLABORATE on a single resource in REAL-TIME
• User can CREATE only CERTAIN KIND of resource
• User can’t DELETE the resource, only ARCHIVE it
• Certain resources are being SYNCHRONISED with other system
• etc.
bit.ly/k-boot-slides
51
52. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Glorified Complicated CRUD
• User can CREATE the resource
• User can READ the resource or multiple resources
• User can UPDATE the existing resource
• User can DELETE the existing resource
• — PLUS —
• User can only UPDATE and DELETE resources they OWN
• User can READ some resources that they were given access to
• User can TRANSFER OWNERSHIP to the other user
• Users can COLLABORATE on a single resource in REAL-TIME
• User can CREATE only CERTAIN KIND of resource
• User can’t DELETE the resource, only ARCHIVE it
• Certain resources are being SYNCHRONISED with other system
• etc.
bit.ly/k-boot-slides
52
53. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Glorified Complicated Valuable CRUD
• User can CREATE the resource
• User can READ the resource or multiple resources
• User can UPDATE the existing resource
• User can DELETE the existing resource
• — PLUS —
• User can only UPDATE and DELETE resources they OWN
• User can READ some resources that they were given access to
• User can TRANSFER OWNERSHIP to the other user
• Users can COLLABORATE on a single resource in REAL-TIME
• User can CREATE only CERTAIN KIND of resource
• User can’t DELETE the resource, only ARCHIVE it
• Certain resources are being SYNCHRONISED with other system
• etc.
bit.ly/k-boot-slides
53
54. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
You Think Your App is Special?
Think harder.
You’ll find distinct CRUD resources with distinct operations,
additional validations, business logic, and side-effects.
Thinking of these “advanced” features as resources will keep your
sanity safe when the going gets complex in the future.
bit.ly/k-boot-slides
54
55. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• > Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
55
56. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Anatomy of a Good Unit Test
The most purest unit tests are for your business domain
bit.ly/k-boot-slides
56
57. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Setup Your Test Suite
Create all the dependencies (as mocks, or as real objects)
Create the object you are testing, inject dependencies via constructor
bit.ly/k-boot-slides
57
58. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Give it a Good Test Name
It has to be readable, and easy to understand, and should
use business domain language and not technical one
Kotlin back-tick function names make it a piece of cake!
And actually making the name good is up to you ;)
bit.ly/k-boot-slides
58
59. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
AAA: Arrange Step
First part of the test body where you setup the state of the world
Create objects you need, and configure mocks here
bit.ly/k-boot-slides
59
60. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
AAA: Act Step
Second part where you call the function you’re testing
Usually, this is the simplest part :)
bit.ly/k-boot-slides
60
61. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
AAA: Assert Step
Third part where you check: correct return value, expected side effect
In the example above, two side effects are verified,
and no values returned
bit.ly/k-boot-slides
61
62. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
AAA Example With Returned Value
Good name
Create objects
and configure all
the mocks in the
ARRANGE step
Call the method
under the test
(notice local variable)
Verify that the
return value is
correct
bit.ly/k-boot-slides
62
63. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
No Framework Dependency
In your business domain unit tests, all dependencies should be
YOURS
If some framework-like things sneaks in, it is a controller, repository,
or some sort of service provider concern.
Move it there!
bit.ly/k-boot-slides
63
64. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s Make The Test Pass (1/3)
Remember: dependency injection is via controller
Next up: let’s create the function
When run: fails as expected
bit.ly/k-boot-slides
64
65. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s Make The Test Pass (2/3)
We’ll make assertions pass one at a time
This one passed—and next one has failed
bit.ly/k-boot-slides
65
66. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s Make The Test Pass (3/3)
66
67. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• > Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
67
68. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Packages: by Role or Concept
VS
What do you think?
bit.ly/k-boot-slides
68
69. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Packages: by Role or Concept
What do I think?
• + Beginner will know where to put
their objects, or find what they’re
looking for by pattern name
• - Changing and deleting the
feature ripples across all the
packages
• - Low cohesion, low modularity,
and higher coupling between
packages
• - Growth is not nice: same amount
of packages, but more and more
classes
• + At a glance anybody will know
what this application is about
• + Most of the things can be (and
should be) made internal/
package-private
• + Often feature can be removed
entirely just by removing a
package
• + High cohesion, high modularity,
and low coupling between
packages
• + Easy to find specific objects,
because you can see everything
about the feature at a glance
bit.ly/k-boot-slides
69
70. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
By concept 1st, and by role 2nd
• + Best of both worlds
• - This has very high max complexity
• Don’t start with it! Or will be painful…
• Refactor towards it, when you have
too much classes in a single feature
package, and for this feature only
bit.ly/k-boot-slides
70
71. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• > Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
71
72. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Repository: JdbcTemplate or JPA/Hibernate
• -/+ You don’t have to map your
domain model to your schema one-
to-one, although you can
• - You need to write your own queries
and row mappers
• - More code
• + Testing is much simpler and faster,
also they tend to be smaller tests
• + More control over queries
• + Every team that I was on, and
used JdbcRepository after JPA
found it rewarding and freeing
JdbcTemplate JPA/Hibernate
• +/- You can easily map your domain
model on the schema and vice
versa, but you have to
• + You don’t need to write queries—
just create methods with right
naming convention
• + Less code
• - You still have to write tests for it
• - These tests are hard to write, and
maintain, and TestEntityManager is
a confusing beast
• - Every team I was on, experienced
only pain with JPA
bit.ly/k-boot-slides
72
73. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why Test JPA/Hibernate?
How likely that I’ve made a mistake there?
It’s still a valid query.
But is it the one I really want?
bit.ly/k-boot-slides
73
74. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Why Test JPA/Hibernate?
Names become code, so I have to test them
The same applies to JPA @Query’ies
bit.ly/k-boot-slides
74
75. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
My Verdict
• JPA is less production code
• JPA is much more test code, and it is often confusing, with too
much framework detail
• JdbcTemplate is more production code
• JdbcTemplate is less test code, and it is often simpler, and talks
more about the behaviour of the repository, not about framework
or even database stuff
Conclusion:
• Use JPA/Hibernate when not TDDing (spike/experiment), then
when hardening after the exploration activity, TDD properly with
JdbcTemplate-based repository
• Use JdbcTemplate right off the bat when TDDing serious
production code
bit.ly/k-boot-slides
75
76. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s TDD a QuizRepository!
A little bit :)
bit.ly/k-boot-slides
76
77. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• > Working with third-party services.
• What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
77
78. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Working With 3rd-party Services
Simple Solution
ImageUploadsProvider
SaaS Provider
QuizService
Mock this in:
- unit tests
- feature tests
Mocking in unit tests is great.
Mocking in feature tests is too
much detail and annoying!
What shall we do?
bit.ly/k-boot-slides
78
79. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Working With 3rd-party Services
Make it an interface with SaaS and Dev implementation
ImageUploadsProvider
QuizService
Mock this in:
- unit tests
FileSystemImageUploads
(interface)(dev, test profiles)
(implements)
SaaSImageUploads
(cloud profile only)
(im
plem
ents)
used in feature tests
bit.ly/k-boot-slides
79
80. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s See The Code (1/2)
bit.ly/k-boot-slides
80
81. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Let’s See The Code (2/2)
bit.ly/k-boot-slides
81
82. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Email Sender Example
Make it an interface with SaaS and Dev implementation
EmailService
SignupService
Mock this in:
- unit tests
StdoutEmailService
(interface)(dev profile only)
(implements)
ImapEmailService
(cloud profile only)
(implements)
used in development
prints email in logs
TestEmailService
(test profile only)
used in feature test
remembers last email
(im
plem
ents)
82
83. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Non-deterministic Behaviour
Not 3rd-party per se, but same principle applies:
TimeProvider
QuizService
Mock this in:
- unit tests
to make it
deterministic
- almost never
need to mock
in feature test
(non-deterministic)
UuidProvider
(non-deterministic)
Mock
this too
These are just wrappers, usually
over some static method
83
84. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Wrapper Code Example
This just wraps the static call
And this is one way to mock it in
the unit test (on mock creation)
This just wraps the static call
And this is one way to mock it in
the unit test (in ARRANGE step)
84
85. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Agenda
• My Development Process Overview
• User Story and Acceptance Criteria
• Outside-In TDD, Feature Tests and UI Tests
• Evolutionary Architecture
• Controller-Service-Repository Pattern (Light and Heavy)
• All Apps Are Just Glorified CRUDs
• Anatomy of a Good Unit Test
• Package Structure: by Role or by Concept?
• Repository: JdbcTemplate or JPA/Hibernate?
• Working with third-party services.
• > What Continuous Integration Really is.
• Feature Toggles.
• Conclusion And Questions.
bit.ly/k-boot-slides
85
86. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
What is Continuous Integration?
bit.ly/k-boot-slides
86
87. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
What Continuous Integration Isn’t
• Having a build server (e.g. ConcourseCI, TravisCI, Jenkins,
TeamCity, etc.).
• Running your test suite after each commit on the master or on the
branch.
bit.ly/k-boot-slides
87
88. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
What Continuous Integration Really is
• You don’t use feature branches.
• You commit and push changes (that pass all tests) to the master
branch very often.
• At least 2 times per hour.
• Experienced CI’ers commit and push almost on every cycle of
TDD (Red->Green->Refactor), which is every 2-10 minutes.
bit.ly/k-boot-slides
88
89. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Wha…? WHY?!
• The process of sharing your changes with your colleagues and
pulling their changes into your code is called “INTEGRATION.”
• CONTINUOUS INTEGRATION in the origin of the term (from
Extreme Programming) meant doing this process continuously:
• Do a very small change.
• Make sure tests are still green.
• Make a very small commit with good message.
• `git pull —rebase origin master`
• `git push origin master`
bit.ly/k-boot-slides
89
90. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
That Answers “Wha…?,” But Why?!
• You update your local branch every few minutes.
• You share your changes with everyone else every few minutes.
• How much merge conflicts do you think you’ll see?
• And if you do, how complex they would be?
• Answer: trivial.
• You don’t need to have 12 staging environments occupied by
developers working on features for 4 weeks.
• You don’t need to juggle 5 WIP branches, and deploy them to
different locations.
bit.ly/k-boot-slides
90
91. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Hold on. What About Code Review?
• Easy :)
• My most preferred option: Pair-program at least 70% of the time.
• 2nd option: Mob programming.
• 3rd option: Review code later together, and instead of fixing
before merging, make better job next time.
bit.ly/k-boot-slides
91
92. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
There Will be Unfinished Features in Master?
• Potentially :)
• Most of the features (when you slice them small enough) will be
still deliverable.
• Other ones you’ll have to feature toggle.
bit.ly/k-boot-slides
92
93. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Feature Toggles
Essentially a smart if statement with configuration flag
Actually, this is a one of prerequisites for real Continuous Delivery
bit.ly/k-boot-slides
93
94. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
There is Much More About Toggles
It probably guarantees a full talk of its own:
different usages, implementations, configurations, and how
to keep them from getting messy
I recommend to read more on MartinFowler’s Blog:
bit.ly/fowler-feature-toggle
bit.ly/k-boot-slides
94
95. What Are The Best Practices When Building a Back-end App With Kotlin And Spring Boot?
Conclusions & Questions
Follow me on Twitter: @waterlink000
Sign-up for my newsletter:
bit.ly/kotlin-newsletter
• Early bird of screencast series:
“Kotlin/Back-End Best Practices.”
• Exclusive articles about Kotlin monthly.
bit.ly/k-boot-slides
95