
Lesson Description
The "JSON Route Handler Q&A" 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 explains that when using an "if" statement with multiple conditions, only the last condition is considered. He suggests using the HTTP package to handle errors and send appropriate HTTP error codes. He also discusses the need to register the handler with the server and explains how to create a new instance of a structure in Go.
Transcript from the "JSON Route Handler Q&A" Lesson
[00:00:00]
>> Maximiliano Firtman: Does it make sense, this? When you have the if with two, there are not two conditions, the condition is the last one.
>> Speaker 2: They can be separated with just colon, as many as you want?
>> Maximiliano Firtman: As many as you want, the last one is a Boolean condition.
[00:00:20]
>> Speaker 2: So in the case of the error right now, would the client just kind of hang waiting for a response? Cuz I'm guessing it wouldn't send it-
>> Maximiliano Firtman: Yeah, we need to do something, so one of the things we can do, let's do it now, is we can talk actually to HTTP and say, hey, you know what?
[00:00:36]
There was an error, send great an HTTP error over that writer, we can pass the error, and what's the code that we wanna pass? For example, do you know what, I mean, if there is an error encoding the JSON? I'm not sure how many of you are aware of all the HTTP server codes that we have available.
[00:00:59]
This response status code.
>> Maximiliano Firtman: When everything is okay, it's 200, so 200 means, okay, so it means okay. Then we have different errors, errors are typically on section four and section five, and that's the prefix of the number. A client error or a server error. So if we have a JSON issue, which group do you think fits best?
[00:01:31]
Client or server?
>> Speaker 2: Server.
>> Maximiliano Firtman: Server, because the client has nothing to do with that, okay? So it's one of the server errors. There are many possible errors, such as, not implemented, the one, wherever you're asking, we didn't do that yet, okay? So the 501, 500 internal server error is that the server has encountered a situation it doesn't know how to handle.
[00:01:57]
Like, I don't know. This is like, I don't know. I don't know what's going on, but gateway service unavailable, gave me time out, blah, blah, blah, there are many, many errors. In this case, I think the one we prefer is 500, it's like, actually, we don't know what happened.
[00:02:15]
Yeah, it was a Shay something, but why? I don't know, yeah.
>> Speaker 2: Why are we using HTTP instead of the response writer to log the http.error?
>> Maximiliano Firtman: So http.error is not actually logging, it's actually creating a new error and sending that error over the writer. So when you look at that, it's feels weird, okay, but error is actually an utility function from the HTTP package that has inside, it creates the header, it sends the right header.
[00:02:50]
It sends the content of the body, so it has a message, and it's also logs that into the operating system. So it's doing a couple of stuff, we don't need to go call this, we can just write directly to the writer, okay? And then we can write a message and we can add the header for the status code by hand, so we can do it manually.
[00:03:11]
HTTP error is actually a function that receives the writer and it's going to send the error to that writer, so to the output. So, we can say, if I handle here, or there are some constants created on the HTTP package for all the statuses. So in this case, it's a status internal server error.
[00:03:35]
I'm keeping the to-do here because I wanna use our own logo. Remember, we created one, so we will get there. Let's do again, baby steps.
>> Maximiliano Firtman: Do I need to return something? Let me first try to close this. This is my function right now. Do I need to return something?
[00:04:00]
Do I need to return the movies in GitHub movies because it's called GitHub movies?
>> Speaker 2: No, but you don't return it just gonna hang in there.
>> Maximiliano Firtman: Yeah, but will it hang in there? So, hang in there means like an infinite loop, something like that.
>> Speaker 2: It's just gonna wait for the response.
[00:04:19]
It's not gonna return.
>> Maximiliano Firtman: So actually, I don't have any synchronous code there anywhere. So, I mean, I could do an infinite loop or something like that, and that will keep their hanging up there. But actually, when it comes to the end of the function, the function will end.
[00:04:40]
So the question is, should I return the movies, or something like that? Well, if you look at the signature, this is a handler, and I don't have that, so I don't have any return type, so I don't need your return. Where are the movies? So I'm sending the movies through the writer.
[00:05:00]
So actually, I mean, it's not clear when you read the code the first time at least, that we're actually sending the movies, where? Actually here.
>> Maximiliano Firtman: So, we are encoding the movies in your JSON and we are sending that to the response rider. So the response writer is actually the output.
[00:05:22]
Does it make sense?
>> Speaker 2: So do you explicitly return the writer then, or?
>> Maximiliano Firtman: No. No, because I'm not creating a new writer. I'm not returning a writer. I'm receiving a writer. Who is sending the writer? The HTTP package. I'm the handler, the HTTP package is saying, hey, here you have the brighter and the request.
[00:05:44]
The information you need is here in the request, and when you have a response, use the writer, just right here. So I don't need to create it, I need to return it. I just need to use it, and I'm using it right now here. Actually, I'm mostly using it here.
[00:06:01]
If there was an error, I'm using here. So that's how handlers work. It's giving me here an error with my literal. I have a name, have the casting, think missing the trailing coma, okay?
>> Maximiliano Firtman: And it's not casting its first name, not name, that's a model, okay, there we go.
[00:06:27]
And now I'm getting the same error as you are saying here. You're saying, cannot use error variable interpret type error as a string value, why? Because it needs the error message that will be sent to the user, and this is the error type that the JSON encoder is giving us.
[00:06:47]
So here we can just use any message, such as, in case you wanna send that, to be honest, most of the time, to the user, you just wanna say, internal server error, I'm sorry. Because if you say here, JSON problem, you're sending too much information to the client.
[00:07:09]
Maybe for your internal login, you want to send detail from the error, but not for the user. This is what the user will see, okay, makes sense?
>> Maximiliano Firtman: Okay, do you have any questions how that works? I know that we are not seeing anything yet, but we promise you that then every piece will fit together and it will finally work.
[00:07:37]
We are just, again, doing baby steps. Then when we have another baby step that looks pretty similar to the previous one, we will probably use more copy and paste because it's just the same, so we can speed up the process. Again, this is dummy data, I'm trying to serve dummy data to the client and this is a movie handler, will it work?
[00:07:59]
Actually created a handler, but I didn't register the handler with a server, okay, so I created the value with a function, but the server will never know that I have it, okay? So in the main.go, here, I may add another handler, okay? If not, it's not gonna work, does it make sense?
[00:08:24]
So,
>> Maximiliano Firtman: How do you work with that? So I need to add another http.Handle for example, api/movies/top, that's the path that I want. And then I need to pass a handler. The thing is that the handler is a value, I'm not sure if you remember that. So I need to pass, actually, what's the handler?
[00:08:50]
I need to pass from movie handler, get top movies. But this is a method, so let me explain that if I remove this, now it's not a method, it's a function, it's an exported function, okay? So, meaning that, I can go here and say, from MovieHandlers,
>> Maximiliano Firtman: Remember, we have a package here, actually, handlers.
[00:09:14]
So from handlers, I will take GetTopMovies without parentheses. Be careful, because when you press Return or Enter in your computer BS code, because it's a function, adds parentheses, so executes the function. And now I wanna pass the function as an argument, okay? And yeah, give me an error, we can solve the error, but anyway, it's not what I want.
[00:09:42]
So what I want probably is, if we look at the error, it says, I cannot use that because it has an invalid phase. So something is different in the interface, but I don't wanna do that. What I wanna do is, I wanna use my option because I created an option.
[00:10:01]
I'm not sure if you remember that, but here I created an object. And I actually want a method. So now I have a movie handler and structure that has a method. So what I need, I need to create an instance of that. So I need to create, for example, the movie handler or handlers, however you wanna call this, and how to create one of those.
[00:10:29]
Remember, how do you create a new instance of a structure in go?
>> Speaker 2: You just do the new something.
>> Maximiliano Firtman: New?
>> Speaker 2: But I mean, it's not, we don't have it.
>> Maximiliano Firtman: Not new, like this. This is not JavaScript, no. So, I mean, one way, remember, we have the structure, movie handler, that's the name, so we can do this, okay?
[00:10:53]
So now, we can say movie handler, get the movies, and now it's not complaining anymore, okay? So a movie handler, we need to be careful that is coming from the package handler.
>> Maximiliano Firtman: So, what's the problem? I mean, it's not a problem, but if you really want the constructor in Go, we need to create a factory function, that's how that works in Go, okay?
[00:11:23]
So if you want the new pattern, you need to create movie handlers, a new factor function. Why are we doing this? Because movie handler, we have different handlers, one for get top movies, another one for get your favorite movies, another one to get the details of one movie.
[00:11:44]
So we have several hundreds just in one structure, okay, that's why we're doing this, okay, just that. So let's move, again, baby steps. So we still have a problem there, there is an error there, there is no working. So let's solve that and then move forward one step.
[00:12:07]
Well, the error is that, remember that, we did that before, we have two type of handlers. It can be a value or a function. In this case, gettopmovies is actually a function. So, actually we need to change handle with handle func. So that's to solve that little problem.
[00:12:28]
But then, the next step is to finish the logo part, because if you remember, our movie handler has at some point, a to-do. So let's try to see how to solve the problem. I'm not sure if you remember that I created a structure for the movie handler, why?
[00:12:50]
Typically, we create structures when we have some data to store. So, something that we can do here is to store a logger. So remember, our logger, so we can store a logger, so we can say that we have a logger. And remember, our logger is actually here is this structure, the type logger.
[00:13:17]
So we're going to receive one logger like this, and also we need to remember that when we are doing this, if we don't use a pointer, we might have a problem at some point. In the future, maybe, because, for example, when we are passing that logger as an argument, it's creating a clone, a copy, okay?
[00:13:46]
When we do that we will start, the idea is that because we get top movies, it's actually a method of movie handler, it can actually access that logger. We will solve the problem the error in a second, but we will actually be able to do that through this variable, h.
[00:14:06]
So this is kind of the this that we have on OOP based languages in Go, okay? Remember that when we are doing a method, the object is actually in this kind of a special argument that we have here, okay? So, we will solve this problem in a second, but that will be the next step, okay, to connect the logger to our movie handler.
[00:14:33]
But because we will do several steps, we will not just add the movie handler, but also the database connector here. Because remember, right now it's just a static, and a static list of movies is not our final code. So we will have more data here, so there is a to-do here.
[00:14:53]
So we will fill this with more data.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops