Summary
In this episode, we lay the foundations of the application architecture by exploring the Model-View-Controller (MVC) pattern and how to adapt it for Go. We discuss the three core components—Models for data and business logic, Views for presentation, and Controllers for coordinating requests—and why MVC emphasizes separation of concerns, making code predictable, testable, and maintainable. We then scaffold the base project structure by creating folders for models, views, controllers, commands, routes, and config, setting up a clean foundation for building a real-world Go application in upcoming episodes.
Transcript
So in this episode, we will be laying the foundations of the application architecture that we are going to be using to build this block. We will talk about what Model-View-Controller or MVC is, how we can adapt it to Go, and we will also scaffold the base project folders. This is simply a way to define Model-View-Controllers at a high level and connect it to another important concept, the separation of concerns. MVC is an architectural pattern that can be done in a lot of different ways. We are just going to be having these three packages: Model, View, and Controller. You could also do this on a resource base, so you would have a user package. I think that is probably overdoing it when starting out, so we are just going to have very clear separations of what is a model, what is a view, and what is a controller. So these three components at a glance: we have models that are simply data plus business logic. This is the only layer that we will have any interaction with the database, so fetching it, storing it, creating it, updating it—all of this has to go through the Model Layer. Then we have the View Layer, and here we will in this course do HTML-based views. You could adapt this to also do JSON views in a sense, because the only real thing here is that the view is just the outward representation of whatever is returned from the server. So you could also have defined views for your APIs in here. Finally, we have the Controller Layer that is simply a way to coordinate requests between models and views. So in a very basic form, we will just have our request come in. If it has some data, we will grab that data, send it to a model, and then return a response through the views based on whatever the model returns us. You can also extend this with services or background jobs. There's a lot of options here, but we will just have this: we pass it, we chuck it into the Model Layer that then returns a response, and then based on that response, we will render a specific view. Right, so models here define the core domain pieces. So for our use case here, think of a user or an article or a newsletter. This is how we control how data is accessed, manipulated, and encapsulated in business logic. The View Layer is about presentation and they can return HTML, JSON, or any other format. We try to keep them as dumb as possible. They should simply render what they are given in most of the cases. We could have some logic depending on, let's say, if you have a user that's logged in we might show something to them, but it's based on what we provide them from the Controller Layer. And the controllers are simply the glue. They accept the request, they invoke some models, and then they hand off the response to the View Layer. A mental model for these is traffic control. They orchestrate request-response flows. So why does MVC help and why is it a really good pattern to start with? Well, it emphasizes the independence of layers. Teams can work in parallel if you get to that point. Refactors can be localized and predictable. Redesigning the UI should not require changing any of the business rules, but we can have the business rules drive a change to the UI. It's predictable, it's testable, and it's also a lot easier to maintain for a long period of time. We also have some things that we don't want to do. Some critiques of classic Model-View-Controller which is that it's very inheritance heavy and that doesn't map one-to-one in Go, which is okay. Our goal here is separation of concerns. We are not trying to mimic what you would see in object-oriented languages like Rails or Django. In practice, MVC works really great in Go when we learn to lean into the strengths of Go. So interfaces, packages, and small composable units. Hopefully you will see when we get through the course that just applying the overarching concept of MVC to Go is actually pretty straightforward and maps really well for how Go works. We don't need this object-oriented approach to actually do MVC in Go. And I also mentioned here the pattern boundaries. So we should just think of what is a model on a conceptual level, what is a view on a conceptual level, and not as much the names we are giving to them. So that's what I said in the beginning. You can have, let's say, a user folder that has all the logic, so it's more of what goes into the layers or what goes into the certain file. So we always do data in a Model Layer and we always do views in a View Layer, and not necessarily where they are in the folder or overarching folder structure, right? So we are going to be following the idea of MVC, which is clear responsibilities. We are going to be using interfaces and packages instead of inheritance, and we're going to keep the layers clean, explicit, and composable. So just in a second we will be scaffolding the base structure of the project. We will be creating all of these folders so we have a base to work from in the upcoming episodes. We want to have something that looks like this where we have the main entry point in command/app. We have the main business logic in models. We have template response rendering in views. We have request handling and orchestration in a controller folder, and we'd also need some routes so we can register a route with our controller and easily reference it throughout the application. And we also need a config so we can have what are known as env variables that would be our secrets, so we can access the database or access third-party services. So to begin, we are going to initialize a Go module, so we say `go mod init bleeding-edge-blog`, which then created this go.mod file here. Then we will create the model, view, controller folders, so on Linux this is `mkdir models views controllers`. Then we're going to create our command directory where we will create an app folder as well. Then we will create router and routes, and finally we will create config. So if we jump in now, we have a bunch of folders with nothing in them yet, but this is the folder structure that we are—the base folder structure we're going to be working with in the course. We will be adding to them over the next episodes so we have a more complete base to work from when we actually start building the blog. But this is where we are going to start, and all of these will hopefully make more sense once we have been through the next upcoming episodes and modules. So to recap: Model-View-Controller gives you some clarity about what goes where and also how to mentally think about certain layers of your code. It's scalable. We will adapt this to fit Go's strengths, and then we are basically ready to start tackling real-world projects. So in the next episode, we will dive into models and we'll start shaping the domain.
