Inheritance in huge DTOs - api

I have two applications, namely A and B.
A calls a rest API from B and passes a huge dto with 46 field in the body. I need all that data in application B. But as a new requirement, I must add 4 more field to this dto in order to handle another kind of request that needs all the other 46 fields.
I managed it by using inheritance concept. Now I have 2 rest APIs to handle each type and there are some places where I have to use condition on type of the objects to avoid duplication.
I thought I was preserving single responsibility principal.
But I wonder if it's the right way to have 2 rest APIs for such matter since it propagates complexity to client. Is it better to have a flat object and a single API?
And if inheritance is a good solution? (Because of duplications and conditions on type of objects).
And, is this OK to have such a huge dto and pass it around? Is there anyway I could avoid it?

Looks like you confuse REST APIs with endpoints, or the question does not make much sense. Having two endpoints for 2 operations e.g. POST /B/v1/x1 {body1} and POST /B/v1/x2 {body1+4fields} is totally ok. Posting two different request bodies to the same endpoint can be ok too if they do almost the same thing POST /B/v1/x1 {body1} vs POST /B/v1/x1 {body1+4fields}. As of DTO inheritance I prefer splitting it up to smaller DTOs and have a bigger DTO which is a composite of the smaller ones {p:{p1,p2,p3,...}, q: {q1,q2,q3,...}, f:{f1,f2,f3,f4}}. With this approach your additional 4 fields f can be optional. Generally speaking we avoid inheritance and follow to composition over inheritance principle. https://en.wikipedia.org/wiki/Composition_over_inheritance

Related

Usage of data entities to exchange between client and microservices (asp.core)

Usually i create dto's to get data from microservice (WebApi) to client (MVC).
But sometimes it's cumbersome to duplicate structure of data entity to dto, especially if entity has multiple fields and many embedded relationships.
So i have to duplicate fields and relations.
Can i use data entity instead of dto?
I use a special assembly for dto's to be exchanged between client (MVC) and given microservice. Should my data entities live in this assembly?
This is a common complaint that derives from not understanding the concept of bounded contexts. Because you're deep in the code, you just see two things that look like the same thing, and you have had, like all developers, the idea beaten into your brain that you should not repeat yourself (DRY).
However, the key word above is that the two things look the same. They are in fact not the same, and that is the critical salient point. They are representations of domain objects from different contexts (data store and application layer, for example). If you use the same object, you are tightly coupling those contexts to the point where they're now inseparable. As such, the very concept of having multiple layers becomes moot.
A related concept here is anti-corruption layers. This is a layer you add to your application to facilitate communication between two different application contexts or domains. An API is a form of anti-corruption layer. Again, because you're building all the apps, it seems like they're all the same thing. However, imagine your MVC app as a third-party application being built by someone else to consume your API. Should they use your entities directly? No. They probably would have their own entity classes and their own data store. The DTO your API uses provides a way for these two different applications to communicate via a common language. If you use your entity classes directly, then any change to your data, necessitates a change to your API, which in turn necessitates a change to any consumers of your API. Imagine if Google changed a database column, and because of that, every single developer using their API(s) had to immediately make changes to their own applications or they would break.
In short, just because two classes look the same, doesn't mean they are the same. Your entity and your DTO are each representations of a concept in different contexts, and therefore you need and should have both.

REST WCF - best approach to expose entities or convert custom classes to Entity classes vice versa

I have taken a step back on two of the approaches in my project (WCF REST Service).
Started with WCFDataServices since it support full OData service stack, but due to more validation requirements on CRUD operations, switched to 'WCF Service' with EF.
And now thinking to step back to use Self-tracking entities to exposing entities to client, as many articles says STE is no more supported by Microsoft and preferred to use OData.(but again WCFDataService not suitable for me).
Please suggest what is the best design here to expose my entities over client.
Alternatively, I may have to write custom classes (Data Contracts) of Entity Model. But, this increases code (for conversion of objects between Custom and Entity) and decreases maintainability.
Please suggest is there any best approach to expose my entities. Your suggestions are valuable and most appreciated.
Fowlers first law of distributed object design states, "don't distribute your objects". This just means give them a copy and not the actual entity itself. If you were to create mirror copies of your entities in your data contract namespace, you retain much more flexibility, should your database schema need changing. If your data contract is initially identical to your entity, a tool such as AutoMapper will eliminate all the conversion code you need to write. Once configured, to convert your entity to your data contract becomes a 1 liner:
Mapper.Map<CustomerDto>(customer);
This takes your customer entity and gives you back a new customer dto. It's all convention based and works by matching up property names. Even if the data contract isn't entirely identical to the entity, you only have to prompt AutoMapper for those properties it can't figure out for itself.

CQRS Naming Conventions

I'm implementing a new webservice and while I'm not yet using CQRS I would like to create my service so it could easily be moved to CQRS in the future. So, I'm wondering about naming convention for my DTO classes and also my methods.
I've read this blog post on DTO naming conventions and it seems sensible to me. It suggest the following ...
SomeSortOfQueryResult
SomeSortOfQueryParameter
SomeSortOfCommand
SomeSortOfConfigItem
SomeSortOfSpecification
SomeSortOfRow
SomeSortOfItem (for a collection)
SomeSortOfEvent
SomeSortOfElement
SomeSortOfMessage
What I'm asking here is how I should name my methods. Is it good practise to use GetSomething or would SomeQuery be better?
Naming should really just come out of the thing the method is doing. Take a step back and looking at Command-query separation (CQS) first. What you're really trying to do here is make sure that any given method is either querying for data or commanding that something happen.
I.e. "Asking for a value should not change the value".
CQRS is something different, on a larger scale, and generally less well understood. It's not necessarily complex, though, just applying the CQS concept at an architectural level rather than a code level. You might choose WCF for commands and raw SQL for queries, for example. It aims to allow you the freedom to make your queries the simplest thing that could possibly work, while your commands still get the richness of a full Domain Model or other suitable implementation for your business rules.
CQRS also steers you away from a CRUD application, to a task-based one where you focus more on the problem domain in terms of user interactions than just reading and saving data.
Queries
Generally I name "queries" variations on FindXYZ(), GetXYZ() or LoadXYZ, as long as the intent is clear (i.e. return some data, don't modify any).
Commands
Typically commands are harder to name, though you can think in similar terms to PowerShell's cmdlet naming conventions - verb-noun. Personally though I tend to implement commands as a CommandProcessor pattern, where commands are actually objects containing parameters (sometimes only a primary key of an entity). There is the code to look for appropriate "processors" for each command's Type. Typically in CQRS you'd try and keep this synchronous, because async means you have more work to do with respect to handling commands that failed to be processed, but if you really need a command to be async, then your command's handler might send a message to an ESB to do so.
Talking about DTOs in the context of CQRS rings alarm bells for me where you are specifically talking about the query side. Quoting that blog article
the DTO (Data Transfer Object) pattern was originally created for serializing and transmitting objects
A CQRS architecture implies a thin query side to me i.e. you don't have lots of layers where you need to move information between them with serialized objects or DTOs. It might be that you're using the term DTO in a different sense.
That doesn't really answer your question but I wanted to point it out.

Should entities have behavior or not?

Should entities have behavior? or not?
Why or why not?
If not, does that violate Encapsulation?
If your entities do not have behavior, then you are not writing object-oriented code. If everything is done with getters and setters and no other behavior, you're writing procedural code.
A lot of shops say they're practicing SOA when they keep their entities dumb. Their justification is that the data structure rarely changes, but the business logic does. This is a fallacy. There are plenty of patterns to deal with this problem, and they don't involve reducing everything to bags of getters and setters.
Entities should not have behavior. They represent data and data itself is passive.
I am currently working on a legacy project that has included behavior in entities and it is a nightmare, code that no one wants to touch.
You can read more on my blog post: Object-Oriented Anti-Pattern - Data Objects with Behavior .
[Preview] Object-Oriented Anti-Pattern - Data Objects with Behavior:
Attributes and Behavior
Objects are made up of attributes and behavior but Data Objects by definition represent only data and hence can have only attributes. Books, Movies, Files, even IO Streams do not have behavior. A book has a title but it does not know how to read. A movie has actors but it does not know how to play. A file has content but it does not know how to delete. A stream has content but it does not know how to open/close or stop. These are all examples of Data Objects that have attributes but do not have behavior. As such, they should be treated as dumb data objects and we as software engineers should not force behavior upon them.
Passing Around Data Instead of Behavior
Data Objects are moved around through different execution environments but behavior should be encapsulated and is usually pertinent only to one environment. In any application data is passed around, parsed, manipulated, persisted, retrieved, serialized, deserialized, and so on. An entity for example usually passes from the hibernate layer, to the service layer, to the frontend layer, and back again. In a distributed system it might pass through several pipes, queues, caches and end up in a new execution context. Attributes can apply to all three layers, but particular behavior such as save, parse, serialize only make sense in individual layers. Therefore, adding behavior to data objects violates encapsulation, modularization and even security principles.
Code written like this:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
can be refactored like so:
Book book = author.WriteBook();
printer.Print(book);
publisher.Publish(book);
customer.Buy(book);
reader = new BookReader();
reader.Open(Book);
reader.Read();
reader.Highlight();
reader.Bookmark();
librarian.GetRelatedBooks(book);
What a difference natural object-oriented modeling can make! We went from a single monstrous Book class to six separate classes, each of them responsible for their own individual behavior.
This makes the code:
easier to read and understand because it is more natural
easier to update because the functionality is contained in smaller encapsulated classes
more flexible because we can easily substitute one or more of the six individual classes with overridden versions.
easier to test because the functionality is separated, and easier to mock
It depends on what kind of entity they are -- but the term "entity" implies, to me at least, business entities, in which case they should have behavior.
A "Business Entity" is a modeling of a real world object, and it should encapsulate all of the business logic (behavior) and properties/data that the object representation has in the context of your software.
If you're strictly following MVC, your model (entities) won't have any inherent behavior. I do however include whatever helper methods allow the easiest management of the entities persistence, including methods that help with maintaining its relationship to other entities.
If you plan on exposing your entities to the world, you're better off (generally) keeping behavior off of the entity. If you want to centralize your business operations (i.e. ValidateVendorOrder) you wouldn't want the Order to have an IsValid() method that runs some logic to validate itself. You don't want that code running on a client (what if they fudge it. i.e. akin to not providing any client UI to set the price on an item being placed in a shopping cart, but posting a a bogus price on the URL. If you don't have server-side validation, that's not good! And duplicating that validation is...redundant...DRY (Don't Repeat Yourself).
Another example of when having behaviors on an entity just doesn't work is the notion of lazy loading. Alot of ORMs today will allow you to lazy load data when a property is accessed on an entities. If you're building a 3-tier app, this just doesn't work as your client will ultimately inadvertantly try to make database calls when accessing properties.
These are my off-the-top-of-my-head arguments for keeping behavior off of entities.

Should I avoid message inheritance in WCF?

Generally, I try and avoid using inheritance in WCF contracts, preferring composition.
But in the following situation...
I have a service operation that can result in one of two things: ResultA and ResultB.
There is a boolean/enum in the response message to report this outcome.
There are a number of other properties in the response message. Some of these are only relevant in the event of ResultA and some are only relevant in the event of ResultB.
I see my options as being:
Have a single response message contract that contains everything and when properties are not relevant, they are left as null. The client then has to look at the bool/enum to see if its ResultA or ResultB and ignore properties accordingly.
Have 2 response messages contracts, both inheriting from a shared base. One representing ResultA and its relevant properties and one representing ResultB and its relevant properties.
I much prefer option 2 for a number of reasons, but it breaks the composition over inheritance rule.
What do people think?
My gut feeling here is "redesign your interface". Having methods with dubious return types is generally not a sign of good design. This leads to a lot of unnecessary and error-prone logic in every caller of the method.
So I would suggest "secret option number 3": refactor the interface into two separate methods.
All rules are meant to be broken. If you are reusing objects and the systems allows you to use inheritance... why not use it? As Phil Haack puts it... think for yourself.
Limiting yourself by a set of artificial rules is a great way to make you work much more difficult. There is a reason we can use inheritance, and I say this is one of them.
Prefer Composition Over Inheritance (Steve Rowe) Here is another angle. But if you read it he is talking about the reuse of function, not data.
Prefer composition over inheritance != Never use inheritance :-)