3

I am traditionally a desktop app developer, but circumstance has thrust me into the role of doing web client and corresponding REST api logic for a project I am involved in. Unfortunately, I'm a one-man-show, so my opportunities to learn new patterns or techniques from co-workers is somewhat limited. When I was ramping up, I had the opportunity to work (briefly) with a contractor who exposed me to the idea that my server REST logic should be separated into a Controller (where the actual GET/PUT/POST/DELETE methods live) and a Service that does the heavy lifting. As it was explained to me, the Service might further interact with one or more Providers or Stores.

My understanding is that a Provider would wrap logic that interacts with another system, maybe another web API, or a weird bit of legacy code, or maybe some proprietary bit of hardware (like a temperature guage, for example). Additionaly, a Store would wrap the CRUD logic for actual data objects to SQL, NoSQL, text files, whatever.

Assuming all this makes sense, and is indeed how the pros do it, he further advised me to incorporate the naming into my classes, like this:

PizzaController might proxy the received web API calls to the PizzaService, which in turn could talk to both the PizzaProvider and the RefridgeratorStore.

I'm not 100% positive this is how the real world does things - but it made enough sense to me to sound credible and I've generally adopted this pattern and so far it has worked well enough to organize my logic.

But this is where a few questions comes in:

First, is this view of the separation of my classes really how others structure their code? And if I am close, but not quite, what corrections should I be making?

Second, is it legitimate for one Service to instance and leverage a second Service? For example, what if my PizzaService has to decide if we want delivery or we are going to make a pizza from scratch - it might want to either invoke the PizzaProvider -or- it might simply want to defer to the PizzaMakerService. If the PizzaService doesn't make this decision, then the decision logic would have to live earlier in the food chain (no pun intended). That would infer my PizzaController would have to decide if it should use the PizzaService -or- the PizzaMakerService; and that doesn't smell right to me.

And finally, (following the pattern I was shown) my Services frequently return a data object back to my Controller, where the Controller will map one or more properties into a ViewModel that is returned to my client. I've found that I could just as easily map the relevant bits of data into a anonymous object (C#) on the fly and return it to my client. The returned JSON is the same, so why introduce the class definition for a ViewModel at all? Is there a taboo against just crafting an anonymous object in the Controller and returning it?

I realize (in my situation) I can pretty much do anything I want - how I name classes, how I separate logic, if I use anonymous objects - it's really entirely my code. But these questions have been nagging at me for a while, and I'd like to be doing things as close to 'correctly' as possible. It's likely these questions (or a variation) have been asked and answered before, so I'll apologize now for any duplication - but for the life of me I can't seem to find any direct answers.

Thanks!

  • that contractor led you to the correct path, keep walking it. – Pedro Rodrigues Jul 6 at 11:08
0

First, is this view of the separation of my classes really how others structure their code? And if I am close, but not quite, what corrections should I be making?

This is how many suggest to structure their code. But it is my opinion that such rigid structure might hinder some design decissions, especially when you don't understand the reasons behind this kind of structure. I personally find addition of Service to be unecessary, and if such abstraction is needed, then it is not related to the controller, but to the business logic that should be executed.

The main reason for this kind of separation is test automation. This is why Provider and Store are abstracted away. So they can be replaced by test doubles within automated tests.

Second, is it legitimate for one Service to instance and leverage a second Service?

I see why not. As long as Services are loosely coupled with Controllers and are more representation of business behavior than just second part of the Controller.

Is there a taboo against just crafting an anonymous object in the Controller and returning it?

I don't think there is anything wrong with this. But I would advise against it. C#'s big advantage is static typing. And you should leverage it. For example, some code documentation tools (like Swagger) might make use of the returned type to generate a documentation to your endpoint, which will then include the returned structure. That cannot be done with anonymous type. Also, if you have automated tests written against your Controller, then returning an anonymous type will make it more difficult to access returned data by the test.

| improve this answer | |
  • @geo... I agree with this answer. I would add only just some tiny comments here. The Store is usually called Repository. The Provider is usually called either Adapter or Facade. The Provider is too generic and it does not tell anything about the purpose of the object itself. While the Adapter and Facade in conjunction can be used as an Anti-corruption layer between your system and the 1st / 3rd party. – Peter Csala Jul 21 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.