質問

We are developing a system with coarse microservice architecture. We have an API that uses controllers and back-end logic with Entity-Framework repository, and several types of clients that use this API, all in dotnet, therefore, typesafe.

We need to use some sort of data transfer objects for communication between the API and the clients. Clients are using REST calls. However, our controllers need to hide some properties of the entities for:

  • different clients (e.g. metadata of entity for web clients and no metadata for mobile clients)

  • different controller actions (e.g. /Users/ returns a list of User DTOs having only name and surname, whereas /Users/{id} returns user details. )

  • different REST methods (e.g. a Post requests would not have timestamps as it is created server-side)

My question is: what would be a good design for reusability? Is the best practice creating new classes for all requests/responses? We wouldn't want to use dynamic objects. I thought of Builder pattern, but I am not sure if that fits here.

役に立ちましたか?

解決

My suggestion is that you use a single derived class containing all properties in common for a given entity. For example a User class with first name, last name, and last logged in timestamp.

To represent data coming from mobile device, you have a derived version of User called MobileUser extending the existing properties with your meta information pertaining to a mobile user such as mobile device type, resolution, etc.

Everywhere in your web application where you only need User, you use only User. In the parts of your program where you need to differentiate, you implement that in User. For example, to persist User instance to the database, you'd call its User.save() method. User.save() would be responsible for saving all properties common to all derived classes and MobileUser.save() would be responsible for saving the properties specific to MobileUser. Logic would dictate that you would use separate tables in your database as well, though you're free to do whatever you deem is best.

Of course, don't fill these methods with the logic of calling the sql query and such. Rely on another class to perform generic persistence operations passing the data that you wish to persist to the method. You could use a UserDAO class to save User instances and MobileUserDAO to save MobileUser instances. It doesn't matter. The crucial thing is that where the separation in your program is required, you do so without having to figure out its type.

For what concerns returning the data, a facade pattern would probably suit you well enough here. The idea is that you separate the actual entity data from where and how it is used. You could use a facade wrapping an entity to make available only the properties you wish to return keeping private properties hidden away in the part of your program that doesn't use it.

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top