So, at the moment I find myself building my c#/.net
(web) application ( or folder/project/package-...) structure often like this, thinking about it in a "somewhat onion-architectural way":
myApp
- API
- Controllers for HTTP, REST etc., may even be a whole gui, though ...
- Domain.Model
- "Business Logic" for the actual application, being most
of the time a (micro)service...
- Interfaces for Repositories, Thirdparty(see below)...
- Infrastructure
- ThirdParty
- Call to other Services,
- Persistence
- Implementations for Repositories
- Adapters
- Adapt some Class to a DTO for my domain
- Config
- global configurations...
- Tests
- empty... just kidding.
Actually, I like to have this Separation a lot, giving me a good overview about:
- what is really "of value" at the moment (inside the Domain.Model)
- what is just "presenting the data" (API)
- what are "The surrounding, may-be-changing dependencies" (Infrastructure)
So, I'm going to start a new job in a few weeks, going back to the java world and we'll make heavy use of spring (boot/cloud) to create a new application. For thus, I think about using the industry-standard hibernate-ORM, but besides, I found it very helpful to have a lightweight OR-Mapper like JDBI, too. And I actually read a lot about Hibernate being slow at scale, and I know the same behaviour when it comes to entity Framework.
Now I look for Spring boot examples, and I remember one does not need to use an Implementation of a Repository to actually use the repository using Spring Data.
A typical Spring Repository implementation might look like this:
Public interface PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
...
}
So, I'm asking myself where to put this interface now? At first glance, I'd put it into my Domain.Model package as the Repository Interface it is.But doesn't spring "in the background" create an actual implementation inside(!) my domain.model, then, thus coupling it to a persistence technology, an OR-Mapper, and so on?
In .NET, I actually just create a simple I[Class]Repository inside my domain, and add the actual implementation in my Infrastructure, like Entity Framework or Dapper. This allows me to very easily switch OR-Mappers, even the whole DBMS. Thus, doing it like this in Spring would result in creating a ton of boilerplate-code for CRUD operations, because I can't use the CrudRepository Interface, or am I wrong here?
So, would it be better to just create a "plain" Repository inside my domain.model? But wouldn't that be just the start for the ton of boilerplatecode I actually want to avoid?
Perhaps I should just not "work against the framework" here, for in last consequence, I'd have to do it for every other Call to spring components, too, when I want to be 100% consequent in abstracting my domain from the actual technology..?
I'm a bit lost here, it actually feels like a knot in my head at the moment. Perhaps I'm even missing something obvious.
I hope you could give me advice by either clarifying how the spring repository implementation works and why it is okay to have it inside Domain.Model, or showing me my structural misconception whilst giving me advice to a better structure for my projects.
Thanks in advance!
domain
do not expose the basic crud/pagingandsorting methods, only your custom ones. Isn't this limiting and preventing you from utilizing that functionality from within your service class?