title: Application layers in Spring application
body: <p>I'm participating in implementing rest API application and we're sticking to Spring Boot as a framework.  </p>
  
  <p>We're at the very beginning of implementing the system but even at this stage of the project, it starts to feel like it is something wrong with application design.</p>
  
  <p>We have 3 layers in our application: </p>
  
  <ol>
  <li>Controller layer - at this layer we (some of this is done automatically by spring):
  
  <ul>
  <li>receive requests from our clients</li>
  <li>convert it to dto object and validate this dto </li>
  <li>convert dto and logged in user information to some object or DB entity (!) to make a call of the Service layer.</li>
  <li>return result to the client as dto object which is converted from some object or DB entity (!)</li>
  </ul></li>
  <li>Service level - at this layer we:
  
  <ul>
  <li>do all the business logic, e.g. external services calls</li>
  <li>change/create/delete entities via Repository layer calls</li>
  <li>return result of the business logic as some object or DB entity object (!)</li>
  </ul></li>
  <li>Repository level - at this level we specify the logic which returns database entities to the Service level.
  
  <ul>
  <li>make queries to our DB to get entity and return it as is to the service layer  </li>
  </ul></li>
  </ol>
  
  <p>My concern about application design described above:</p>
  
  <ol>
  <li>All application layers know about DB entities</li>
  <li>It should be pretty difficult to control sessions, transactions and all the stuff at a minimum in cases when entities have lazy-fetched proxies.</li>
  <li>Not sure, if we need to, but we can introduce some type of ServiceDto so the contract is the following: 
  
  <ul>
  <li>Controller coverts validated client dto to ServiceDto and call Service layer with it as an input</li>
  <li>Service performs business logic with the use of ServiceDto and convert the result of business operations and ServiceDto to DB entity and calls Repository layer with it as an input</li>
  <li>Repository accepts db entities and returns DB entities as it was before</li>
  <li>The only thing that can be pretty harsh here is a mapping between all these DTOs</li>
  </ul></li>
  </ol>
  
  <p>It will really help to see some type of guidelines, best practices or projects which shows how to organize communications between application layers in this type of application.  </p>
  
  <p>Thanks a lot!</p>
  
  <p><strong>Additions below</strong></p>
  
  <p>Some code snippets:</p>
  
  <pre><code>class OrderController {
      @Autowired
      private OrderService orderService;
      @Autowired
      private UserService userService;
      public OrderResultDto createOrder(OrderRequestDto dto) {
          return orderService.makeOrderRequest(userService.getAuthenticatedUser(), dto)
      }
  }
  
  class OrderService {
      @Autowired
      private OrderRepository orderRepo;
  
      public makeOrderRequest(User user, OrderRequestDto dto) {
          // do some complex business logic
      }
  }
  </code></pre>
  
  <p>It seems not ok to assign dto we send to frontend as JSON to Service contract... Moreover, if we need to call this service from another method, that method will be bound to this dto as well which is not good.</p>