What are the responsibilities of the data layer?


I'm working on a project where I had to add a data layer to my application. I've always thought that the data layer is purely responsible for CRUD functions ie. shouldn't really contain any logic but should simply retrieve data for the business layer to manipulate.

However I'm a little confused with my project because I'm not sure whether I've structured my app correctly for this scenario.

Basically I'm trying to retrieve a list of products from the database that fall within a certain pricing threshold. At the moment I have a function in my data layer that basically returns all products where price > min threshold and price < max threshold. But it got me thinking that maybe this is incorrect. Should the data layer simply return a list of ALL products and then the business logic do the filtering?

I'm pretty confused over whether the data layer should simply provide methods that allow the business layer to get raw data or whether it should be responsible for getting filtered data too?

If anyone has an article or something explaining this in detail it'd be very helpful.


The purpose of the data layer is to do the data related interactions with the data repository. If you want to get really pure, you can separate your data layer into two parts: the Data Abstraction Layer and the Data Independence Layer. The DIL is responsible for assembling the correct query for the data repository you are interfacing to (e.g. you might offer a choice of SQL Server or Oracle), while the DAL sits over top of the DIL and calls the appropriate methods to get the data it needs (for example it might specify the stored procedure to call or table/view to query, but the DIL is responsible for actually doing the call).

In your case I would remove the filter at the data layer, i.e. the caller should pass in the thresholds. In pseudo code, your method signature would look like this:

public YourDataObjects[] GetProducts(decimal lowerPrice, decimal upperPrice) { ... }

I've used an array for the return type because pretty much all languages have that (you didn't specify which language you're using), this is also the reason for using the decimal type for thresholds.