I'm in the school of thought of 'thin controllers', and love to push logic down into services and the domain models. However, I'm wondering if my controller should be making an HTTP Request to another web service or if the application service should do it. It seems that with my school of thinking then "yes" I should push it into the application service. However, this means the application service is stuck with HTTP only. So if I want to use a different communication protocol I'll need to implement another service like RabbitMQService
instead of HttpService
.
For example:
public Controller {
// POST api/controller
[HttpPost]
public async Task PostAsync([FromBody] Dictionary<string, int> data)
{
// get data from input json
var output = service.doWork();
// prep output data for outgoing HTTP Request
// this here or in a service like 'HttpService'?
await _sender.PostAsync(host + "/api/xxxxx", data);
}
}
Or have the application service send the PostAsync
request?
1 Answer 1
Hmm your Controller doesn't seem very 'thin' to me. I would have
public Controller {
private IElectionService service; //possibly sends over http or Rabbit or whatever
// POST api/controller
[HttpPost]
public async Task Vote(string electionId, string candidateId)
{
await service.Vote(electionId, candidateId);
}
}
We can imagine that the ElectionService has various injected services
public class ElectionService : IElectionService
{
private IElectionRepository repo; //calls election api
public async Task Vote(string electionId, string candidateId)
{
var election = repo.GetElection(electionId);
if(election.Candidates.Includes(candidateId))
{
repo.AddVote(new Vote(electionId, candidateId));
}
else
{
throw an exception!
}
}
}
public ElectionRepository_Http : IElectionRepository {...}
public ElectionRepository_RabbitMQ : IElectionRepository {...}
etc
-
This is exactly how I feel that it should be done.keelerjr12– keelerjr122019年03月29日 12:08:30 +00:00Commented Mar 29, 2019 at 12:08
-
-
So the repository should be dealing with communication?? Or do you mean something like
HttpElectionService : IElectionService
?keelerjr12– keelerjr122019年03月29日 12:29:29 +00:00Commented Mar 29, 2019 at 12:29 -
1you could do it all in the service I suppose. I just naturally separated it outEwan– Ewan2019年03月29日 12:32:55 +00:00Commented Mar 29, 2019 at 12:32
-
So the repository should be dealing with communication
repository should deal with data sources. Whether they are connections or access to the file system is irrelevant to theElectionService
. That's the point of the repository abstractionLaiv– Laiv2019年03月29日 12:42:46 +00:00Commented Mar 29, 2019 at 12:42
ElectionService
to retrieve aElection
by Id likeelectionService.GetElection(electionId)
. And then useElection
to vote for a candidate withelection.Vote(candidateId);
. After the vote is recorded, I make another HTTP request to the candidates. This is not very RESTful and not the way I'd ever design/develop an application. But it's a demonstration in making API calls between web services.