英文:
In Which Layer, Dao or Service, Should I Parse a Rest Client Response?
问题
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);
}
}
英文:
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);
}
}
答案1
得分: 4
以下是翻译好的部分:
这是我对设计的看法和意见。
- DAO是一种抽象持久性操作的模式,应该仅用于处理持久性操作。
- DAO模式有助于将持久性机制/操作或数据访问操作与客户端分离,并且设计遵循SRP,使切换到新的持久性类型变得容易。而且,持久性机制/数据源的更改保留在DAO层中,不会上升到服务层。
- 服务层负责处理和计算数据上的业务操作。它使用DAO/存储库/客户端来获取需要操作的数据。
考虑上述要点,这是我对现有设计的看法以及我如何做的方式。
- 正如chrylis之前提到的,DAO是数据访问对象,不应该关心数据是从数据库还是通过HTTP获取的。
来自Oracle关于J2EE模式的文章中写道:
> 使用数据访问对象(DAO)来抽象和封装对数据源的所有访问。DAO管理与数据源的连接以获取和存储数据。
它进一步说明:数据源可以是持久存储,如关系型数据库(RDBMS),外部服务,如B2B交换,存储库,如LDAP数据库,或通过CORBA Internet Inter-ORB Protocol(IIOP)或低级套接字访问的业务服务。
- 考虑到这些因素,我会在DAO中进行调用,解析响应并将业务对象发送到服务。
- 考虑到SRP,服务不应该知道是通过HTTP调用,数据库调用还是从平面文件中读取的。它只需要知道,一旦我查询数据,我会从DAO得到一个带有所需数据的对象。
- 如果服务负责解析,那么如果数据源明天发生变化,数据就位于原地。所以现在你的DAO发生了变化,因为它现在与数据库交互,而不是发出HTTP请求。你不能再返回一个字符串表示了。你需要一个数据映射器,将某种对象表示返回,这意味着你的服务类也会发生变化。因此,数据源的一次变更不仅会改变DAO中的代码,还会波及到业务层,这会破坏SRP。
- 说到这一点,由于没有长时间开发经验,也不是来自软件工程背景(我曾经以为数据访问对象只能来自数据存储,但多亏了chrylis的评论,让我读得更多,思考数据源和数据存储之间的区别),我总是更喜欢将其命名为客户端->RestClient并进行调用,将我的数据库操作保留在DAO/Repo中。原因很简单,明天看起来会更容易。看一眼类名,就能轻松理解它在做什么,或者这个类可能正在处理什么样的操作。
所以,是的,调用和解析应该发生在DAO/Client中。
英文:
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.
答案2
得分: 3
Dao层严格来说是用于管理包括在持久性机制中的信息,例如:数据库、LDAP等。因此,当您处理外部端点时,将该功能“包含”在服务中是一种更广泛使用的方法。
回答您的问题,第一选项更好。
-
您将所需的业务逻辑包含在了了解外部端点返回格式/信息的类中。
-
使用上述类的外部类将管理一个已知的对象(而不是原始字符串值)。
-
对于外部端点的某些升级(例如响应格式的更改),可以更好地在您的Dao类中进行管理,而不会影响使用它的其他类。
英文:
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.
-
You are including the required business logic into the class that knows the returned format/information by the external endpoint.
-
External classes that use the above one will manage a well know object (instead of a raw string value)
-
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.
答案3
得分: 0
将其放入DAO层。因为解析不是业务功能。此外,DAO层旨在访问来自数据库或其他第三方实体的数据。因此,在从DAO层返回数据时使用正确的POJO格式在我看来是有道理的。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论