Search code examples
c#model-view-controllermvvmviewmodel

Difference between ViewModel and Entity


I'm a little confused about this, I'm asking for help from experienced and knowledgeable friends.

  • View model: an object that I can use to show data on the UI side
  • Entity: get to the database side,the object where I can perform post operations

Everything is okay so far. I have a scenario like this: I have an API resource and a mobile application available. In the application, I project the data that I will show on the screen to the screen by holding it in view model objects.

So is it necessary to meet the future data by the API through view model objects? Or is it correct to create an entity object and match the data received from the API with this entity object and apply automapper to view model objects?

Another question that is running through my head is as follows: I will make a POST operation by the application, should the object to be posted be a view model or an entity?

For example, the username and password are being posted. Do I need to transfer the information I get from the screen to the view model object and post this object, or do I need to move it to the entity object and post this?

It may have been a little complicated, but I wanted to express myself in the best possible way. There are many resources on the internet, and they all say the same thing.

I like to research fine details, thank you.

I am developing a project and I want to do it in the right way. I would like to ask for your support for a question that bothers me.


Solution

  • Ok, I'll try help you simplify the way of think about these abstractions that are sounding confuse to you now, but it's pretty simple:

    ViewModel is an object that has a certain data structure that will be available to your UI. Depending on what is the UI technology/framework, will may have specific logic and behavior, it will act as a data holder usually bindable.

    Entity is an object that will represent a self contained state, may contain data and behavior that will perform according to the business requirements of your application.

    In most cases, viewmodels and entities will look almost the same, but it's a good practice to keep objects focused on its responsibilities.

    What you're missing is the DTO (Data transfer object). This kind of object is that we use when making requests/get responses from API/External Layers.

    When we make an API call to a server, we receive a response which usually will contains JSON data. Then we must handle this response, building an object, mapping properties and values of this object (the viewmodel) and so on. To call and API, usually we take data from Viewmodels, maps them to DTO's and them send through the wire.

    The role of a Entity is enforce data and behavior, which may or not have the same shape of UI models or DTO's.

    EDIT:

    Suppose we have a login form, presenting inputs for username, password and a checkbox for "Keep me signed in". We also have a Boolean flag that will tells us the form is Valid, i.e., True when all form fields are filled in with valid data, otherwise False. The Login button will be enabled or disabled depending on this value, preventing unnecessary firing of login attempts. Finally we need hold a string message that eventually shows an error text to the user.

    So a viewmodel for this login form could be defined this way:

    
    class LoginFormViewModel {
    
      username: string | null;
      password: string | null;
      persistentCookie: boolean = false;
      isValid: boolean = true;
      message: string | null;
    
    }
    
    

    Notice this viewmodel containing data which will be bound to UI/presentation logic & visual components.

    When user clicks SignIn/Login button on the form, we extract from viewmodel only what we need to make our Login Request.

    
    class LoginRequestDto {
    
      username: string;
      password: string;
      persistCookie: boolean;
    
      constructor(username: string, password: string, pers: boolean) {
        this.username = username;
        this.password = password;
        this.persistCookie = pers;
      }
    
    }
    
    class LoginView {
    
      ctor(viewModel: LoginViewModel) {
        this.vm = viewModel;
      }
    
      onLoginClick() {
        this.doLogin();
      }
    
      async function doLogin() {
        var vm = this.vm;
        var requestDto = new LoginRequestDto(vm.username, vm.password, vm.persistentCookie);
      
        const result = await this.httpClient.Post('/login', requestDto);
        if (result.authenticated) {
          this.setState({
            isAuthenticated: true,
            //etc
          });
        }
      }
    }
    
    

    The viewmodel is tied to necessary data for the view, DTO's will be tied to the request is being made, according to specifications of the API/endpoint,

    EDIT 2:

    LoginView represents some Login form, which provides visual components that user can interacts with. It only contains code that deals with visual feedback. For better code organization, the view uses another class named LoginViewModel, which will store data state in the context of the view. The view reflects data from the Viewmodel, and the viewmodel accepts input from the view, in a two-way data binding. Then, we can create another module in our applications, for example LoginService, which will handle the actions we will need to trigger from the view. So the data flow is: View, ViewModel, Service Or Business Layer (LoginService), then a LoginRequestDto is passed to a Infrastructure layer that will send our object to the target. After that, we may receive a response. We get this data, creating a LoginResponseDto and return it to our service/business Layer. Then we can make decisions based in business logic for what we do next (if was a successfull login or not), redirect to another view/page, present a message to the user etc.