7

I have my own service calling a third party rest service that is returning a text based response.This text based response is not a proper service response and needs to be parsed for content as well as errors. For purposes of discussion, assume the 3rd party rest service cannot be changed.

Given these circumstance I am wondering whether I should wire that parsing into the dao layer or the service layer of my application.I know that the service layer should contain all of your business logic, but I feel like if I don't do the parsing in my Dao layer I am leaking. Is it ok to have logic in the dao for purposes of parsing/transformation in this case or should it be done in the service layer?

Any advice is appreciated.

public void MyDao {

     private RestTemplate restTemplate;
     private ResponseParser responseParser;

     public myDao(RestTemplate restTemplate, ResponseParser responsePaser){
          this.restTemplate = restTemplate;
          this.responseParser = responseParser;
     }

     public MyResponse sendRequest(MyRequest myRequest){
         ResponseEntity<String> responeEntity = restTemplate.exchange(...);
         String body = responseEntity.getBody();
         return responseParser.parse(body);
    }
}

OR

public void MyDao {

     private RestTemplate restTemplate;

     public myDao(RestTemplate restTemplate, ResponseParser responsePaser){
          this.restTemplate = restTemplate;
     }

     public String sendRequest(MyRequest myRequest){
         ResponseEntity<String> responeEntity = restTemplate.exchange(...);
         return responseEntity.getBody();
    }
}

public void MyService {

     private MyDao myDao;
     private ResponseParser responseParser;

     public myDao(MyDao myDao, ResponseParser responsePaser){
         this.myDao = myDao; 
         this.responseParser = responseParser;
     }

     public MyObject process(MyRequest myRequest){
         String response = myDao.sendRequest(myRequest)
         return responseParser.parse(response);
    }
}
  • 3
    Every answer to your question will definitely be opinion based connected with personal programmer preferences. Thus in my opinion separate parsing logic is better due to single-responsibility principle. – jwpol Aug 01 '20 at 18:48
  • For SRP though, it states that a class should only have a single reason to change. I would say that it would be ok to include the parsing in the dao because if the format of the rest response changed, you would need to change the way it is parsed. Therefore they are kind of inherently coupled, no? –  Aug 01 '20 at 18:57

3 Answers3

4

Here are my take and opinion of the design.

  • DAO is a pattern to abstract the persistence operations and should be kept solely to work with persistence operations.
  • The DAO patterns help to abstract away persistence mechanism/operations or data access operations from a data-source from the client and the design follows SRP, making the transition to a new persistence type easy. And the change - change of your persistence mechanism/ data source, stays in the DAO layer not boiling up to service layers.
  • The service layer is responsible to handle and compute business operations on your data. It uses a DAO/Repository/Client to fetch the data it needs to operate on.

Taking into consideration the above points, here is what I think of the existing design and how I would do it.

  • DAO, as chrylis mentioned above, is a data access object and should not matter if the data is fetched from the DB or over HTTP. The article from Oracle about J2EE pattern reads:

Use a Data Access Object (DAO) to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.

It further reads: The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets.

  • Taking these into consideration, I would make the call from DAO, parse the response and send over a business object to the Service.
  • Taking SRP into consideration, the Service should not be aware of the call made over HTTP/ db call made/ reading from a flat-file. All it should know is, once I make a query for the data, I get back an object with the required data from the DAO.
  • If Service is taking care of the parsing, what if the data source changes tomorrow and you have the data in-situ. So now you DAO changes because now it talks to the DB instead of making an HTTP request. You cannot return back a String representation anymore. You need a Data Mapper and will send some sort of Object representation back, which means your Service class changes too. So one change of data source, not only changes your code in DAO but boils to the business layer, which breaks the SRP.
  • Saying this, not developing for long and not from a software engineering background(I had the understanding that data access object can only be from datastore, but thanks to chrylis' comment made me read more and think about the difference between data-source and datastore), I always prefer naming it Client -> RestClient and make the call and keep my DB operations to DAO/Repo. The reason being, it is simply easy to read tomorrow. One look at the classname and it is easy to understand what it is doing or what sort of operation the class is possibly handling.

So, yes the call and parsing should happen in the DAO/Client.

Priyak Dey
  • 1,227
  • 8
  • 20
3

Strictly speaking, Dao layer is used to manage information included in a persistence mechanism like: database, LDAP, etc So when you deal with an external endpoint, "include" that functionality in a service is an approach more widely used.

Answering your question, the first option is a better one.

  1. You are including the required business logic into the class that knows the returned format/information by the external endpoint.

  2. External classes that use the above one will manage a well know object (instead of a raw string value)

  3. Some types of upgrades in the external endpoint (changes in the response format, for example) can be better managed in your Dao class, without affecting to the other classes that use it.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
doctore
  • 3,855
  • 2
  • 29
  • 45
  • 4
    "DAO" stands for "data-access object". If the system owning the data happens to be reached over HTTP instead of JDBC, that doesn't change the nature of the relationship, and it's just as reasonable to have a DAO that uses `RestTemplate` as one that uses `JdbcTemplate`. – chrylis -cautiouslyoptimistic- Aug 01 '20 at 19:43
  • 1
    Myself and one of my mentors have had several "good natured" arguments over this haha. I'm inclined to agree with doctore that it belongs in a service or better yet its own RestClient class. The reason I believe this is because strictly speaking the DAO definition does apply to a "persistence" mechanism and this particular rest service does not persist anything, just parses and returns a response. Now if I was calling a rest service that had crud operations, then I would say it belonged in a DAO. I suppose it all comes down to how strictly you want to interpret the rule. –  Aug 01 '20 at 21:20
0

My opinion is put it in DAO layer. Because parsing isn’t a business feature. Also DAO layer is meant for accessing data from DBs or other third party entities. So having the data in right POJO format while returning from DAO layer makes good sense in my opinion.

Suman
  • 818
  • 6
  • 17