3.1 Building a Basic Web Server
As a Go learning exercise, we are going to build our own basic web server. From scratch. This may sound like a daunting task, but by using a few of the skills you are already learned in previous lessons and adding a few new concepts, you will be able to start receiving and handling requests from the web browser in no time.
1.Introduction3 lessons, 12:09
2.the Basics8 lessons, 1:15:15
2.1Variables and Types11:28
2.2Constants and Comments04:44
3.Building Web Servers in Go4 lessons, 43:38
3.1Building a Basic Web Server10:44
3.2Serving HTML to the Browser12:27
4.Conclusion1 lesson, 01:32
3.1 Building a Basic Web Server
Before I go any further, I have to tell you, congratulations, you have made it quite far into the world of the Go programming language. And in many instances, that would often be good enough. You've learned a lot about the basics of program structure, how to write Go code, how to get Go installed on your system, how to create some basic applications and a lot of the functionality there in. Now, as I mentioned, that would be pretty good in most instances, but I feel like you can take this even farther. Yes, you can take the knowledge you've already learned and you can go apply it and create simple applications or utilities and really go on your merry way. But, using the knowledge you have gained over the last dozen or so lessons, you can actually take that knowledge and apply it into an whole another world, and that is of web applications. Now you might think that might be a big jump. I don't know a lot about web applications or maybe I'm only focusing on doing sort of utility work and things like that, and that's fine. But I want to show you that the concepts that you've really learned apply to just about any type of application that you can write using Go. So let's start off with a very basic situation where I want to be able to create a web server so that I can handle requests that are made to my application via a browser. And we're gonna handle this in a very simple straightforward way and then we're gonna build on it incrementally to the point where you're basically building an application designed for the web using nothing but Go and a few built-in packages. So as you can see here, we have our basic web server. So what I wanna do now is two things. I need to set up my application to be able to handle web requests that are coming in to a specific URL, and then once I've realized that a request has come in, I need to do something with it. I need to handle that request. So it's two very simple steps. So the first thing that we're gonna need to do is we're gonna need to import some additional functionality. So we're going to import a new package, and that package is net/http. And HTTP package is going to allow you to use a lot of functionality that will allow you to issue requests to go out to the Internet and do things like that. But it will also allow you to receive requests, but let's not get ahead of ourselves. Let's start out with the basics. So the first thing that I wanna do is, I want to create a function. And this is gonna be a relatively simple generic function for the time being. That is going to kind of be our handler of web requests that come into our server that we can hand off to this. And it's gonna process and do something with it. Albeit, it won't be anything fancy for now. But you'll kind of see where we're going with this. So the first thing that I wanna do is I wanna create a function and you can give it really any name that you want, but I'm gonna call this handler since this is going to be our request handler. Now this handler function, as you're gonna see in a moment, needs to have a couple of pieces of information. It needs to know how it is going to respond or what it's going to use to issue a response. And then it also needs to know what is the request that was coming in so that I can do something with it if necessary. So those two things are going to be types that are built into the HTTP library or to the HTTP package. The first one is going to be a writer and that writer I'm going to call w and it's going to be of type http.ResponseWriter. So that's gonna be the first argument to my handler function and the second one is going to be the request, or not just necessarily the request, but a pointer to the request. So I'm gonna call this r and this is going to be a pointer to an http.Request, just like that. So nothing too abnormal outside of, you've probably never seen those types before. We've never talked about HTTP response writer or HTTP request but you know that those are arguments to a function and that's all you really need to know. And one of them just so happens to be a pointer. Not a big deal, we've talked about these concepts before. So now, what do I want to do? Well, all I really want to do at this point is I want to provide some output to the user in the web browser that we got your request and I can acknowledge that in some way. So what I'm actually going to do now is I'm going to use a combination of our format package or fmt package along with HTTP. So I'm gonna start with format and I'm gonna use another function that's similar to print line but in this case it's actually going to be Fprint line. And what Fprint line is going to allow me to do is take in an IO writer as you see here. Now these are called interfaces. We didn't talk a lot about interfaces but interfaces are just a generic way to describe a type of an object and some of the functionality that it has on it. So this is assuming that the first input into this particular function is going to be an io.Writer and it just so happens that ResponseWriter is one of those. So what I wanna is I want to call my Fprint function and I want to pass to it my writer, which I'm doing here in, with the variable w. Then I need to give it a format and we've used the print F function before so I can provide to this a formatted string that's going to allow me to output something to the user. So in this case I'm gonna say, Hello there. And we're gonna use a formatted string here so I can input some value into this or input some string into this spot in my output and I could say something like, isn't Go amazing. Just like that. And then the last parameter, the last argument to this function, is gonna be whatever parameters it is necessary to fill in this formatted string. And I'm gonna do this quite simply. I'm going to get the request that was issued to me. I'm gonna look at its URL and then I'm going to grab a parameter off the end of that. And you're gonna see what that's gonna look like and why I'm gonna do that in just a moment. So I'm gonna say r.Url which is a property of of the Request. And then I can get the path which is going to give me the path of the URL request that has come in to me and that is a string. But I don't need the whole thing and I'm actually going to slice it. And I'm gonna grab one colon nothing. So I'm gonna go off to the end of the string. Now we can tweak this a little bit in a few minutes and you'll see why but this is gonna get us started. So we have our handler function that's taking in a ResponseWriter and a HTTP request. And I'm going to do a fmt.fprintf so I'm gonna write something out to extremes which is really what we're doing here. So that's fine but now we have to wire this up somehow. And how are we gonna do that? Well, I'm gonna come into my main and I'm gonna use a couple of functions that are going to allow me to not only register this handler to handle requests but I'm also gonna start up a web server. So the way that I'm gonna do is using http and I want to use a handle func or handle function and within here, I need to specify two parameters. I need to specify what request I'm looking to handle and then the handler that I want to use for that request. So in basic HTTP terms, what I'm creating a web server or dealing with requests to a web server. When I wanna speak about just a generic request like I'm going to the root of my web application, we typically talk about it with respect to a forward slash. So that's our base path. And then I need to specify the handler, which is going to be our handler function right here. And that's it. So now I've got this registration of a request coming into my web server and passing it off to a handler. Now I actually need to start my web server, and the way that I do that is, I say, http.ListenAndServe. And on here I can specify an address. So in my case, I'm gonna be running on local host so I'm gonna specify only a port. So I can specify pretty much any port number I want here. I like to use 9000 but you can use just about anything you want. And since we've already specified a handler for a specific request, we don't really have to worry about this handler. So we're just gonna call this nil or nothing, don't worry about it. We're not gonna handle servicing a request through ListenAndServe, we're gonna handle it through our handle function. So let's go ahead and save that. Now let's go ahead and spin this guy up. So I'm actually gonna open a terminal at this point and I'm gonna go into my folder where this BasicWebServer.go exists and I want to run it. So I'm gonna say go run BasicWebServer.go, just like I've done in the past. This is nothing different. And I'm gonna hit Enter. And you'll see that it just kinda sits there. Which might seem a little bit strange, because we do have this print line down at the bottom, but I don't see that here. And the reason for that is because main function is being executed here. It's registered our handler and then it hits this ListenAndServe and it basically stops here and says, I'm not gonna execute any further in my application because I'm listening for requests. And I'm gonna continue to do that until you physically force me to stop, which is good because we wanna start issuing some requests. So let's open up a web browser. And as you can see here, I'm on the Go Lang site. And I'm simply going to go to localhost port 9,000, because that's ultimately what I put into my application. And you can see here, I get my response. I see, Hello there, with kind of a weird space, coma, isn't Go amazing? So that's great but what happened to that whole slice of the URL pathing. Well, the reason that I did that is because what I can now do is I can go into my URL and I can add in a slash and put in a name. So let's put in Derek and I get, Hello there Derek, isn't Go amazing? So using that URL path slice, I can grab parameters off the end of the URL. And I could change this to be anything that I want. I could have it be Frank, and it's going to greet whoever, who's ever name is put on to the end of the URL string. So that's a nice little trick. So in only about a handful of lines of code, very simple stuff that you have learned the basic concepts of to this point in the course, you can now see how to not only spin up a web server but also handle basic requests. Now the response isn't all that interesting just yet and we'll get there. But using just a couple fundamental concepts that you've really learned nice and gradually and slowly over the last few courses, you can now get to the point where you can not only build a basic web application, but you know how to serve it up and actually talk about some of those basic concepts.