Pergunta

My api is exposing information centering around an entity Company. Companies are complex, and can contain Vendors directly, or can contain sub-companies which contain vendors themselves.

A consumer of our API has asked for the addition of several new endpoints from which they can request information about a company and its vendors; the catch is, for these new endpoints, they want all the company's vendors listed and merged in with its sub-companies' vendors.

The transformation would be as follows:

Company1         ==========>     Company1
|                                |
+--Vendor1                       +--Vendor1
+--Company2                      +--Vendor2
   |                             +--Vendor3
   +--Vendor2
   +--Company3
      |
      +--Vendor1
      +--Vendor3

Currently, the architecture of the project is based on Clean-Architecture / Onion-Architecture with four major project categories:

  1. Web Api
  2. Use Cases
  3. Data Access
  4. Business Objects

The transformation logic is in actuality, much more complicated than the example above, and will be needed multiple places, so placing the logic directly in the API controller methods is obviously a no go.

Since this is an interface concern, one could make an argument for having a function in the WebAPI project which does the transformation. This would require the least new classes since the DTO which represents the data sent to the requester could be re-purposed, but this method represents the least ability to reuse (we are are considering making a non-http API as well).

The method which I am leaning towards is to create a dedicated UseCase for the merge. This seems to me to be the best balance of re-usability and simplicity.

Another option is to create the method in the Company business object itself, because what knows how to transform a company better than that company? Simple to use, all the data and logic are in one place, and very reusable. But, then we have to figure out what format to return that transformation in, and all that can get very complicated if we want to attempt to reuse the business objects already in place as the return format.

I'm sure there are other options which I have not thought of too.

What are architectural best practices / advice for where to place this entity transformation logic?

Foi útil?

Solução

In short you are taking a hierarchy of objects and flattening them (a little).

Putting this in a Use Case would make sense if use cases can be composed of other use cases, or if there was only one use case that needed this behavior.

Unless you can come up with a good business reason for this consolidated view of the vendors of a company other than "I don't want to see duplicate vendors", then I would lean towards a use case for this one.

If you can come up with a good business reason, then a new business class would be the way to go, and push this into the enterprise-wide area of the architecture.

Then again, maybe KISS prevails here, and all you need is a method on a Company object that returns a unique list of vendors from the whole company hierarchy. You are free to use this in any use case you see fit.

Licenciado em: CC-BY-SA com atribuição
scroll top