Hi! I created a backend based on the Clean Archite...
# server
e
Hi! I created a backend based on the Clean Architecture principles. Feedback would be very much appreciated! The application is separated into three modules: Domain, Usecases and Adapters • Domain module contains all entities, it's validation and repository interfaces • Usecases module performs actions on the domain entities and repositories and does authorization The domain and usecase modules do not have any external dependencies. • Adapter layer: each adapter is implemented as a standalone module, lowering dependence on specific frameworks and libraries and making them interchangable. The server module consumes all adapters (e.g. databases, (graphql) endpoints, authentication logic) GraphQL endpoints are auto-generated from the Usecases Used technologies: Ktor, JWT, Exposed, Flyway, KGraphQL/GraphQL generated endpoints. https://github.com/ESchouten/CleanArchitecture
👏 3
e
Maybe nitpick, but could be useful about modeling or representing your domain model: https://www.47deg.com/blog/functional-domain-modeling/
👍 4
e
Interesting article! To some extent it's even already implemented with the value classes defined in the domain module, e.g. Email, Password and Password hash classes and the Authority enum. The value classes even do input validation in their init block
e
ok, I totally misread your class, I was reading plain String for email. Apologies. Cool stuff tho!
👍 1
e
Don't worry! I really appreciate your feedback
@Joris PZ Long time no see! I am curious what you think about this type of architecture and the implementation I made, since I've received valuable feedback from you in the past at Ximedes. Only at your convenience ofcourse
j
Hey @ESchouten long time indeed! It's very busy right now but I'll add looking over your code to my personal backlog - nice!
😁 1
d
@ESchouten for your value types you might find values4k useful, as it give you pre-packed typesafe factory/parse/show functions through an extendable companion object : https://github.com/fork-handles/forkhandles/tree/trunk/values4k You can also vary your programming model to use result types instead of exceptions.
e
@dave Thanks for the feedback! What's the added value of values4k over the new value classes released in Kotlin 1.5? Currently, I am doing validation in their init blocks, see https://www.github.com/ESchouten/CleanArchitecture/tree/main/domain%2Fsrc%2Fmain%2Fkotlin%2Fcom%2Ferikschouten%2Fcleanarchitecture%2Fdomain%2Fentity%2FUser.kt Returning result types might indeed be a better way communicating more complex messages or multiple messages to the client, though I really like the simplicity of throwing an exception. Time for some experimenting. 👍🏻
d
values4k is completely compatible with value classes. The thing it adds is to provide a consistent interface for construction which doesn't rely on the init blocks, plus the parsing/showing functionality which is separate to the class implementation. This allows you to do :
Copy code
PaymentDate.ofResult(someDate): Result<PaymentDate>
... which is much preferable from an FP validation point of view as exceptions break control flow. You can also add support for any monadic type by just adding an extension function to the ValueTypeFactory (which becomes the companion object). If you look at the code, it's been done with
of()
,
ofResult()
,
ofResult4k()
... Additionally, you can then provide different parse/show implementations for different purposes - so say you want to represent PaymentDate as "YYYY-MM-DD" for one system, but then want to parse/show it as "YYYY-DD-MM" on another, this is trivial toplug in.
👍 1