Introduction
One of the most important concepts for a SAP Commerce developer is understanding how the different layers of an application work together.
If you have worked with SAP Commerce, you have probably seen classes such as:
Controller Facade Service DAO Converter Populator
But why do we need all these layers?
For example, when a customer requests product information from the storefront, the request may travel through:
Browser ↓ Controller ↓ Facade ↓ Service ↓ DAO ↓ FlexibleSearch ↓ Database
The response then travels back:
Database ↓ DAO ↓ Service ↓ Facade ↓ Converter / Populator ↓ DTO ↓ Controller ↓ Browser
Understanding this architecture is extremely important for SAP Commerce development, debugging, performance optimization, and interviews.
1. What is Layered Architecture?
SAP Commerce applications generally follow a layered architecture where each layer has a specific responsibility.
A simplified structure looks like:
┌─────────────────────────────┐ │ Controller │ ├─────────────────────────────┤ │ Facade │ ├─────────────────────────────┤ │ Service │ ├─────────────────────────────┤ │ DAO │ ├─────────────────────────────┤ │ FlexibleSearch / DB │ └─────────────────────────────┘
Additional components such as Converters and Populators are commonly used between the facade/service domain models and DTOs.
2. DAO Layer
DAO stands for:
Data Access Object
The DAO is responsible for retrieving and persisting data at the data-access level.
In SAP Commerce, DAOs commonly use:
FlexibleSearchService
For example:
public interface ProductDao { ProductModel findProductByCode(String code); }
Implementation:
public class DefaultProductDao implements ProductDao { @Resource private FlexibleSearchService flexibleSearchService; @Override public ProductModel findProductByCode( final String code) { final String query = "SELECT {pk} " + "FROM {Product} " + "WHERE {code} = ?code"; final FlexibleSearchQuery searchQuery = new FlexibleSearchQuery(query); searchQuery.addQueryParameter( "code", code); final SearchResult<ProductModel> result = flexibleSearchService.search(searchQuery); return result.getResult() .stream() .findFirst() .orElse(null); } }
Notice that the DAO knows how to retrieve the data.
It should not contain complex business logic.
3. Why Do We Need DAO?
Imagine your service contains:
String query = "SELECT {pk} FROM {Product} ...";
and you have 20 different methods doing this.
Your service layer becomes tightly coupled to database access.
Instead:
Service ↓ DAO ↓ FlexibleSearch
The service doesn't need to know how the data is retrieved.
This provides:
- Separation of concerns
- Better maintainability
- Easier testing
- Reusable data-access logic
4. Service Layer
The Service Layer contains business logic.
For example:
public interface ProductService { ProductModel getProduct(String code); }
Implementation:
public class DefaultProductService implements ProductService { @Resource private ProductDao productDao; @Override public ProductModel getProduct( final String code) { return productDao.findProductByCode(code); } }
The service calls the DAO.
Service ↓ DAO
5. Where Should Business Logic Go?
Consider this requirement:
Only products with APPROVED status should be returned.
This is business logic.
You could implement:
public ProductModel getApprovedProduct( final String code) { ProductModel product = productDao.findProductByCode(code); if (product == null) { return null; } if (!ArticleApprovalStatus.APPROVED .equals(product.getApprovalStatus())) { return null; } return product; }
The important point is:
DAO retrieves data.
Service applies business logic.
6. Facade Layer
The Facade provides a simplified interface for the presentation layer.
For example:
public interface ProductFacade { ProductData getProduct(String code); }
Implementation:
public class DefaultProductFacade implements ProductFacade { @Resource private ProductService productService; @Resource private ProductConverter productConverter; @Override public ProductData getProduct( final String code) { ProductModel product = productService.getProduct(code); return productConverter.convert(product); } }
The facade hides the complexity of the underlying service and model layer.
7. Why Not Call Service Directly From Controller?
You technically could, but in a well-structured SAP Commerce application, the facade provides a cleaner boundary between the presentation layer and business layer.
Instead of:
Controller ↓ Service ↓ DAO
we typically use:
Controller ↓ Facade ↓ Service ↓ DAO
The facade can coordinate:
- Service calls
- Converters
- Populators
- DTO preparation
- Presentation-oriented operations
8. What is a Model?
SAP Commerce models represent platform items.
For example:
ProductModel CustomerModel OrderModel CartModel CategoryModel
Example:
ProductModel product;
A model generally represents the persisted SAP Commerce item.
9. What is DTO?
DTO means:
Data Transfer Object
For example:
ProductData
might contain:
public class ProductData { private String code; private String name; private String description; }
A DTO is intended to carry data between application layers, especially toward presentation/API layers.
10. Model vs DTO
This is an important interview question.
Model
ProductModel
represents the SAP Commerce item.
DTO
ProductData
represents data that can be exposed to another layer.
Conceptually:
ProductModel ↓ Converter ↓ ProductData
11. What is Converter?
A Converter converts one object into another.
For example:
ProductModel ↓ ProductData
A converter might look like:
public ProductData convert( final ProductModel source) { ProductData target = new ProductData(); populate(source, target); return target; }
In SAP Commerce projects, converters are commonly configured with populators.
12. What is Populator?
A Populator copies data from a source object into a target object.
Example:
public class ProductPopulator implements Populator<ProductModel, ProductData> { @Override public void populate( final ProductModel source, final ProductData target) { target.setCode(source.getCode()); target.setName(source.getName()); target.setDescription( source.getDescription()); } }
The flow becomes:
ProductModel ↓ Converter ↓ ProductPopulator ↓ ProductData
13. Why Use Populators?
Imagine your ProductData needs:
- Basic product information
- Pricing
- Images
- Stock
- Categories
- Reviews
Instead of creating one giant converter, you can have multiple populators.
For example:
ProductBasicPopulator ProductPricePopulator ProductImagePopulator ProductStockPopulator ProductCategoryPopulator
The converter can execute the required populators.
This makes the architecture more modular.
14. Complete Request Flow
Let's consider:
Customer opens
/products/P100.
The request might flow like this:
Browser │ ▼ ProductController │ ▼ ProductFacade │ ▼ ProductService │ ▼ ProductDAO │ ▼ FlexibleSearchService │ ▼ Database
The result comes back:
Database │ ▼ ProductModel │ ▼ Service │ ▼ Facade │ ▼ Converter │ ▼ Populators │ ▼ ProductData │ ▼ Controller │ ▼ Response
This is one of the most important flows to understand for SAP Commerce interviews.
15. Controller Layer
The controller handles the HTTP request.
For example:
@GetMapping("/products/{code}") public ProductData getProduct( @PathVariable final String code) { return productFacade.getProduct(code); }
The controller should generally be thin.
Avoid putting business logic here.
Bad:
@GetMapping("/products/{code}") public ProductData getProduct(...) { // FlexibleSearch // Business rules // Validation // Price calculation // Database operations }
Instead:
Controller ↓ Facade ↓ Service
16. DAO vs Service vs Facade
This is a very common interview question.
| Layer | Responsibility |
|---|---|
| Controller | Handles HTTP/API request |
| Facade | Presentation-oriented orchestration |
| Service | Business logic |
| DAO | Data access |
| Converter | Converts objects |
| Populator | Populates target object |
| Model | Represents SAP Commerce item |
| DTO/Data | Transfers data |
A simple way to remember:
DAO → Get data Service → Decide/process data Facade → Prepare data for presentation
17. Example: Complete Product Flow
DAO
ProductModel findProductByCode( String code);
Service
ProductModel getProduct( String code);
Facade
ProductData getProduct( String code);
Controller
@GetMapping("/products/{code}") public ProductData getProduct( @PathVariable String code) { return productFacade.getProduct(code); }
Complete flow:
HTTP Request ↓ Controller ↓ Facade ↓ Service ↓ DAO ↓ FlexibleSearch ↓ ProductModel ↓ Converter ↓ ProductData ↓ HTTP Response
18. Dependency Injection
SAP Commerce heavily uses Spring dependency injection.
For example:
@Resource private ProductService productService;
or:
@Resource private ProductDao productDao;
This allows classes to depend on interfaces rather than concrete implementations.
For example:
private ProductDao productDao;
instead of:
private DefaultProductDao productDao;
This improves:
- Testability
- Maintainability
- Loose coupling
- Extensibility
19. Interface vs Implementation
A common SAP Commerce pattern is:
ProductDao ↑ | DefaultProductDao
Similarly:
ProductService ↑ | DefaultProductService
And:
ProductFacade ↑ | DefaultProductFacade
This follows the interface + implementation pattern widely used in SAP Commerce.
20. Where Does ModelService Belong?
ModelService is generally used by the Service Layer or other appropriate application services that need to manipulate models.
Example:
public void updateProduct( ProductModel product) { product.setName("New Name"); modelService.save(product); }
The DAO should generally focus on data retrieval/access rather than containing business workflows.
21. Where Does FlexibleSearch Belong?
Typically:
DAO ↓ FlexibleSearchService
For example:
public List<ProductModel> findProducts() { final String query = "SELECT {pk} FROM {Product}"; return flexibleSearchService .search(query) .getResult(); }
This keeps data-access concerns in the DAO.
22. Common Architecture Mistakes
Mistake 1: FlexibleSearch in Controller
Avoid:
@Controller public class ProductController { // FlexibleSearch here }
Better:
Controller ↓ Facade ↓ Service ↓ DAO
Mistake 2: Business Logic in DAO
DAO should not become a business service.
Bad:
if (customer.isVIP()) { // complex business rules }
Move business decisions to the Service Layer.
Mistake 3: Business Logic in Controller
Controllers should remain thin.
Mistake 4: Returning Models Directly to APIs
Avoid exposing:
ProductModel
directly through API boundaries.
Use appropriate DTO/data objects.
23. DAO vs Service Example
Suppose we need:
Get all approved products from a particular catalog version.
DAO:
List<ProductModel> findProducts( CatalogVersionModel catalogVersion);
The DAO retrieves the products.
Service:
public List<ProductModel> getApprovedProducts( CatalogVersionModel catalogVersion) { List<ProductModel> products = productDao.findProducts(catalogVersion); return products.stream() .filter(product -> ArticleApprovalStatus.APPROVED .equals(product.getApprovalStatus())) .toList(); }
The service applies business rules.
24. Why This Architecture Matters
Imagine a project with 500 developers.
Without separation:
Controllers ↓ Database
would quickly become difficult to maintain.
With proper layering:
Controller ↓ Facade ↓ Service ↓ DAO ↓ Database
each team can work within a clear responsibility.
25. Interview Scenario
Question
A product API is taking 5 seconds.
How would you troubleshoot it?
Answer
I would trace the request:
Controller ↓ Facade ↓ Service ↓ DAO ↓ FlexibleSearch
Then investigate:
- Controller processing time
- Facade logic
- Service business logic
- DAO execution
- FlexibleSearch query
- Database execution plan
- Number of records returned
- Converters
- Populators
- Additional nested service calls
- N+1 queries
- Cache behavior
This demonstrates architectural understanding rather than simply saying:
"Optimize the FlexibleSearch."
26. Interview Questions
What is DAO?
DAO is the Data Access Object responsible for data-access operations.
What is Service Layer?
The Service Layer contains business logic and coordinates application operations.
What is Facade?
Facade provides a simplified presentation-oriented API to higher layers such as controllers.
What is Converter?
Converter transforms one object into another, commonly a Model into a Data/DTO object.
What is Populator?
Populator populates a target object from a source object.
Why shouldn't controllers contain business logic?
To maintain separation of concerns and make business logic reusable and testable.
Why shouldn't DAO contain business logic?
DAO should focus on data access. Business rules belong in the Service Layer.
What is the difference between Model and Data?
Model represents a SAP Commerce persistence item, while Data/DTO is generally used to transfer data between layers or expose information to presentation/API layers.
27. Complete Architecture Diagram
The overall SAP Commerce flow can be remembered as:
CLIENT │ ▼ ┌──────────────┐ │ Controller │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ Facade │ └──────┬───────┘ │ ┌───────▼────────┐ │ Converter │ │ Populator │ └───────┬────────┘ │ ▼ ┌──────────────┐ │ Service │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ DAO │ └──────┬───────┘ │ ▼ ┌─────────────────────┐ │ FlexibleSearch / │ │ ModelService │ └──────────┬──────────┘ │ ▼ DATABASE
Conclusion
Understanding DAO, Service and Facade architecture is essential for becoming a strong SAP Commerce developer.
The key responsibilities are:
Controller → Handle request Facade → Presentation-oriented orchestration Service → Business logic DAO → Data access FlexibleSearch → Query data ModelService → Manage model lifecycle Converter → Convert objects Populator → Populate target objects
If you can clearly explain this flow in an interview:
Request ↓ Controller ↓ Facade ↓ Service ↓ DAO ↓ FlexibleSearch ↓ Database ↓ Model ↓ Converter ↓ Populator ↓ DTO ↓ Response
you'll have a solid foundation for discussing SAP Commerce architecture and real-world project development.