Lesson Description

The "Movie Handler" Lesson is part of the full, Build a Fullstack App with Vanilla JS and Go course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano discusses how handlers handle HTTP requests and responses, while repositories handle communication with the database. He also demonstrates how to pass the repository and logger to the handler using an initializer function.

Preview
Close

Transcript from the "Movie Handler" Lesson

[00:00:00]
>> Maximiliano Firtman: What's the deal here? Now we need to send somehow that movie repository to the movie handler. Remember, we have handlers. The handler is the one that is handling the http request, so it speaks http, both the request and the writer, the response writer, okay, that's the handler.

[00:00:21]
Now we have the repository that is picked SQL. It talks to the database, that's the repository. We have the handler, we have the repository. Now we need to connect both somehow, okay? For that, when we go to the handler, probably you don't remember that at this point, but there is a to do here.

[00:00:45]
So the movie handler was a structure with no values, but now we can add value, we can request values here. So for example, we can request that we will have a storage of type. And here I can use movie repository or movie storage. Those are the two types that I have available.

[00:01:09]
Which one do you feel we should use? Movie storage, movie repository? Probably you don't remember both. Movie storage is actually the interface. A movie repository is one implementation of that interface. So which one should I use? The abstract or the implementation one? I'm defining the structure right now.

[00:01:39]
I'm not creating the object, so I should use?
>> Speaker 2: It would be the interface.
>> Maximiliano Firtman: The interface. So why? Because then we can finish the rest of the code without actually knowing which exactly implementation we have. So it's an abstraction layer. So we use the interface, which means, anyone implementing those methods can be used as our storage for the handler.

[00:02:10]
So that will let us in the future change the data provider. Does it make sense? Kind of? Then we can also have a logger as well. We can pass a pointer like that.
>> Maximiliano Firtman: Now complaining that I'm not using the movie repo, which is okay, because I'm not passing it right now.

[00:02:44]
>> Maximiliano Firtman: To the MovieHandler. The logger is, in case you wanna use the same logger, because here, it says to do logger error, so now, instead of that to do, we can actually talk to h.logger, and just this is an error, so we can, log that we have a JSON Encoding error, so we can log that in our logger.

[00:03:07]
So let's look back on this. We get the movies, it's still returning an empty array, so we don't want that, right? So we want to access the database. Actually, that's the goal. So we will get there. So, one more thing is that if you go to main.go, it's complaining a movieRepo is not being used and it's right.

[00:03:39]
So we are creating our instance of movie handler here, okay, at the top. Let me move that down a little bit after we initialize the repository. The thing is that this is the we are contracting the instance here. Well, we can define here. In our movie handler, this is kind of a constructor, right?

[00:04:03]
Or we can create our own factory as well because we need to pass the movie repo. Does it make sense? So the movie repo should go to the movie handler as something very similar as what we did here when we were passing the database. Does it make sense?

[00:04:21]
>> Maximiliano Firtman: Remember, we have the handler, we have the repository. The handler needs the repository. So that's why when we created this, the structure has now the storage. So how can I pass the storage to that movie handler?
>> Maximiliano Firtman: Question for you, .storage.
>> Speaker 2: You just initialize it in line.

[00:04:50]
Couldn't you?
>> Maximiliano Firtman: I can just initialize in line, how?
>> Speaker 2: Storage:
>> Maximiliano Firtman: Storage: here and I pass the movieRepo. The repo, okay? And then we'll see if it's complaining or not and why it's complaining. I can also pass the logger.
>> Maximiliano Firtman: This is the automatic initializer that we have available in go for go structures.

[00:05:20]
This is kind of a new so think about JavaScript. If it is JavaScript, this is gonna be like new movie handler, and you're passing the movie repo and the log instance, and internally, it will save those values. Why is like I cannot access the storage like this. There is a quick and straight answer to that.

[00:05:44]
>> Speaker 2: Lowercase s.
>> Maximiliano Firtman: Lowercase s. My storage is lowercase s, so I can it's not public, if not the other option is you, it was uppercase S, and then you pass it like this from here, like storage = movieRepo, okay? Does it make sense?
>> Speaker 2: But when you do it directly, you don't have to, it doesn't matter if it's upper or lower case.

[00:06:10]
>> Maximiliano Firtman: What I'm doing here. You say? Yeah, because this is kind of an initializer. The idea is that every structure, when you create a structure, you have an initializer, an automatic initializer, where you can pass the values of each property that you have in the structure.
>> Speaker 2: Then it doesn't really matter the case.

[00:06:32]
>> Maximiliano Firtman: No, in that case doesn't really matter. So when you construct an instance of that structure, you can pass anything, okay, make sense? It's complaining because it says, what do you think about this missing coma before new line? Do you know what's going on there with the trailing coma?

[00:07:01]
>> Maximiliano Firtman: So there is a trailing comma always in Go. That depends on how you're writing this, it should be there or not, the trailing comma, okay? To be honest here, there are many ways to solve the problem. So in Go, you decide how you wanna do that. I mean, if you prefer to make the storage public, you can do that.

[00:07:22]
So we go to the handler. The only thing is that S storage like this, or, let's say that they prefer ways to create the new factory, as we did with the other options. Okay, so well, now it's complaining because my logger is L, it's okay. And so movieHandler, so now I can pass the storage from here, so it's up to you, okay, have the movie repo, and then I have the logger like that.

[00:08:03]
>> Maximiliano Firtman: So I think it's a good time to go back to our diagram. Let's see where we are. So we are, remember, at the backend GO. So we have handlers, we have modelRepositories, we have models and the database. So the handler is the one that speaks HTTP. Now the handler has a pointer to a model repository, that repository is in this case, movie repository speaks sequel, so it talks to our tables, and from there it actually creates models to slices of our model.

[00:08:52]
So a collection of movies and is giving to the handler movies. And then the handler will actually take those movies and send JSON back.
>> Maximiliano Firtman: Does it make sense? So we're missing the last part because now our handler here now has movies. It's hard coded, so I don't want that.

[00:09:21]
What do we want? To ask-
>> Speaker 2: Storage.
>> Maximiliano Firtman: Storage.
>> Speaker 2: Method.
>> Maximiliano Firtman: To GetTopMovies.
>> Maximiliano Firtman: Okay, it's giving an error, why? Because the signature of GetTopMovies is two variables, not one. Why is that? Because you may always get an error.
>> Maximiliano Firtman: Makes sense? In this case, the error is being propagated from the database to the repository, the repository to the handler and the handler should send that to the client.

[00:10:05]
Okay, so if there is if error is not nil, so if there is an error nil, what should I do? Now I need to send propagate that error to the client. Client of the handler, I mean, the handler is HTTP, so I should call, for example, the error send this writer, the error is, I don't know.

[00:10:35]
We don't know why, okay, but it's not working. We couldn't get the top movies. So we are propagating the error. We are always receiving the error, and each layer decides what to do. Also here we can talk to our logger. So h, we should have a logger. And we can save something like, let's say, Get Top Movies, error, we can pass the error to our logger.

[00:11:17]
>> Maximiliano Firtman: Okay, make sense? So we have now basic backend in layers. HTTP talks to a handler. Actually we go to main. In main we take based on the URL, based on the path, we use a handler. The handler has all this information. The movie handler has the storage and the logger.

[00:11:45]
So when we get into the handler, the handler is talking to each storage. It's an abstract storage. It's an interface, it doesn't know the exact implementation of that, and it's asking for get the movies and get the movies will go. The implementation of that, it's a repository will go to SQL.

[00:12:05]
There is one disadvantage of using this abstract layer, the interface, is that if I use control click or command click here, I'm not going to the implementation of GetTopMovies, I'm going to the interface. A little issue when you are browsing in your code, because it goes to the abstract one, it doesn't know exactly which one is going to be used in execution.

[00:12:32]
So you need to go and find it here and GetMovies, it's the one that is actually making the query. It's actually this one GetTopMovies. I know it feels like a lot, but once you have it, the rest of the services are more straightforward, okay, and you understand the layers that we have, the handlers, handling http, then we have data repositories that are handling SQL, and they communication between both is the model.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now