DEV Community

Muhammad Uzair
Muhammad Uzair

Posted on

Who should call API in MVC model ? model or controller

while watching a YouTube tutorial for making weather app using express JS , the instructor used MVC pattern to organize code. Where
Controller is used for making API call (to openweather map) and generating views.
Model is used for validating user Input in client side data (city name to search weather for).

The Problem ?

Model only contain few lines of code for validating user input for given user request while controller contain code for generating views for GET request as well as calling API + generating view on POST request.
according to MVC model should interact with data (database) shouldn't call be made and handled from model rather then controller ?

Answer according to internet search ?

By googling same question I get answer controller should call API on top from stackExchange however that answer was non-accepted and less upvoted answer compare to answer from same question which suggest model should be used for API.
by reading few others blogs I found answers totally opinionated. Some of them mentioned 'model' as data itself rather then a component to just interact with data.

What's your answer ? controller or model.

*P.S: the reason i feel like model should interact is because we can call same methods in model from different controllers *

Discussion (17)

Collapse
_garybell profile image
Gary Bell

This is exactly the reason why MVC is flawed. If the controller is for managing application flow, and the model is literally for an object, there's no clear location for any repository level work.

If you have to stick to the rigid 3-tier system, then the Model should likely do it. If it doesn't, then if you need to use that model outside of the one controller you've added the API logic into, you end up needing to either:

  1. Duplicate the logic for calling the API to another controller
  2. Call the controller from another controller for the same model needs
  3. abstracting in a bizarre way for that one model, which is overkill for other controllers

All of the options are code smell to some degree.

Sticking it in the model is better, as it means you can call it in a single manner any time the model is used. ControllerA and ControllerB can both call ModelZ, and ModelZ can use a function to load the required data from the source it needs.

Ideally you'd do neither, and have an additional layer to the application for repository. This would allow you to use the same logic for all model types. It then doesn't matter if you want to load data via a database, API, flat file, or some other odd manner. You can simply call a method like model->load() and it can access the repository information and undertake the action required for populating the model.

Collapse
webbureaucrat profile image
webbureaucrat

I don't think MVC is flawed per se. I just think its often misapplied. MVC is just a design pattern for web programming. A single application always uses lots of design patterns. The problem arises when tutorials introduce them as a way of modeling entire applications.

Collapse
uzair004 profile image
Muhammad Uzair Author

That's nice point, i will look into it.

Collapse
uzair004 profile image
Muhammad Uzair Author

Yeah, that's the reason i think model should call API. Reusability of model methods and avoid duplication from controllers. I think if model apply constraints on data, why don't it call it then. In my case it is small app with one or very few API calls.

Collapse
webbureaucrat profile image
webbureaucrat

Think about what a model is. It is there specifically to model the page state. If you give it more responsibilities, like calling out to fetch data, your model will quickly become too complicated to maintain. Later, if you tried to make changes to your API request code, it could change the way the page state is modeled, which could cause bugs.

Next, think about your controller and what it does. Your controller is in charge of integrating your models and your views. Getting data from an API (or database) is an important intermediate step in this process, so this is a pretty good place for your API call.

As your app will grow bigger, you'll want to move your API calls into a repository layer in order to keep your controller methods from growing very large. When you're ready, look into the repository design pattern and try to implement it in JavaScript. (Most of the time people use databases in the example, but it works just as well for API calls.) If you use a repository, your controller will be calling into the repository, so ultimately it is still the controller making the API request.

according to MVC model should interact with data (database)

You'll find this isn't true for databases or API calls. In the MVC pattern, models only model page state. It is a shortcut to save models to the database. People do it in demos because it saves time, but it will cost you if you try to do it in the real world because in the real world you'll often find that what data you want to have saved doesn't have anything to do with how users will interact with the data. For example, my database model might have a User model that has things like credit card number, password hash, etc. But when I'm writing the users profile page, I shouldn't display sensitive data. And I'll also include a lot of things on the profile page that aren't in my User database model, like the number of friends currently online. So I need a User database model that is not a part of my MVC design pattern and an entirely separate Profile model within my MVC pattern.

If you're not familiar, I recommend you look into the Single Responsibility Principle for further reading.

Collapse
uzair004 profile image
Muhammad Uzair Author

Thanks for detailed answer.
How model in models page state ?

Collapse
webbureaucrat profile image
webbureaucrat

So you decide your controller does too much, and you have a correct instinct to separate things. This is good.

The problem with moving your database call to your model, though, is that your model also already has a job--to model the page state. Now it also establishes database connections and retrieves data? This is problematic because you are still coupling two different concepts when they are better off separated.

Instead, you should move the database call to a new thing that is not dependent on the web-platform-related parts of your app and have a portion of your code that is just dedicated to making database calls and retrieving data, and your controller should call that.

Collapse
sirseanofloxley profile image
Sean Allin Newell

MVC doesn't really tell you how to do something like that (API / db interactions), so you have to combine multiple design patterns to have a sense of consistency. I'd advocate for a domain service layer that the controller layer calls into. The service layer can get interfaces injected into it for DB and API access (Repositories) that are implemented in a different project that depends on the domain/service layer. Models can just be simple POCOs with very simple logic in their methods if any at all, most business rules will be in the service layer, all third party interactions (DB/API) are in repositories, all frontend is in the View, all HTTP is in the API.

Collapse
uzair004 profile image
Muhammad Uzair Author

How to create service layer ?

Collapse
uzair004 profile image
Muhammad Uzair Author

Question edited: added reason why i think model should do API calls.

One important take away from answers is " repository layer" can anyone explain that , how i am gonna have it ? Should i add new file or folder ?

Next question is what model should have it it can't call API ?

Collapse
uzair004 profile image
Muhammad Uzair Author

So you are using model for interacting with database.
What if you need different API calls with different parameters ( user input city name to search for weather ) ?

How do you apply constraints & error handling on those calls. Let's say user input should not be empty or record for entered city isn't found after making API call.

Collapse
shadowtime2000 profile image
shadowtime2000

I believe models are kind of purely data classes and shouldn't have that much logic in them.

Collapse
uzair004 profile image
Muhammad Uzair Author

What kindda code it should have then ? In my case ( weather app) it only have clase for handling empty user input

webbureaucrat profile image
webbureaucrat

This does make a difference, but I'd still separate out a repository layer that just handles database related stuff.