Lesson 72
Intro to Golang (Building a JSON API) - Software School (2024-08-24)
The lecture goes over how to use the Go programming language to build a backend server API that communicates using the JSON format for data.
First make sure to install Golang, as the language is also called. The lecture gives you a brief intro to Go with a hello world program.
Then it goes over how to establish an HTTP server with the net/http module. You learn how to define an endpoint with a handler function.
Later on, you learn how to define the structure for a JSON response and return that.
Throughout the lecture the instructor gives numerous insights about the Golang programming language itself and its many quirks.
Video Transcript
Okay, everybody, let's talk about Golang and how to make a simple JSON API today.
First, you need Golang or Go, the programming language.
This is the website, go.dev, you click download, choose your system, and then install it.
Once you got it installed, if you go to any command proper terminal, you should be able
to type go, space, version, and it will let you know what version is installed.
In my case, I'm using 1.22.5.
One of our members just installed it, and it's 1.23, that's fine as well.
Anyway, make sure you got Go installed, once we got that, I'm going to make a directory
here called intro to Golang, and inside that, I just created the directory of MKDIR, space
JSON-API, this is the command to create a directory, it should work on any system, MKDIR in the
name of the directory.
If you're welcome to use your graphical user interface like Finder or Mac, or Windows Explorer,
or whatever, use on Linux, Nautilus, I guess, on GNOME.
Anyway, I got the JSON-API directory, I'm going to use OpenDat in my favorite text editor.
For this, today I'm going to use Visual Studio Code, which is freely available for everybody.
Okay, so, let's see here, this is it, let me see if I can open more specifically JSON
API.
I just open it more, okay, and for the purpose of using Go, there's an extension that you
can install, if you click extension tab, look for Go, you want to find the Go extension
for Visual Studio Code, or whatever editor you're using, you should have a similar thing.
I think if you use JetBrains, they have the GoLand program, ID, anyway, I have this installed,
you click install, it should give you a lot of cool stuff about auto-completion and code
documentation, and so on, very powerful.
Anyway, here I am in JSON-API, I'm going to create a new file, I'm going to call it main.go,
the extension for Go is Go, okay, and then here when you have a Go file, you have to
declare at the top of the file the package, this belongs to, let's call it package main,
and then let's make the main function to, that will be the starting point of the program.
So to make a function in Go, just type the fun keyword, and then let's call it main,
and then parentheses, and then curly braces, by the way, the curly brace has to be in the
same line as the name of the function, otherwise it will give a compiler error.
And then we can type whatever here between the colored braces, let's for the sake of
simplicity, I'll just print a message to the screen to see if it's compiling and working.
To do that, we need to import the module FMT, so FMT.println, parentheses, double quotes,
hello.
And by the way, you notice this squiggly line, that's from the extension that's telling
me this is undefined, it doesn't know what FMT is, so we have to import it at the top
with the import statement, import space, double quotes, FMT, that's the name of the module
that provides this method or function called println.
By the way, if you notice when you have Go modules imported, and the function names always
start with a capital letter, because that's the way Go uses to be able to make the function
available outside of the module, so you have to have the capital P there.
So the case matters.
Anyway, I saved that, and another thing about if you don't know about Go, you might be
new to the language, it's very strict about many things, and it tries to be as simple
as possible, so there's only one way to do the thing.
For example, there's only one way to loop, only one if, there's no if or unless like
other languages like Ruby.
And also the spacing that Go uses for indentation, I don't know if you can see it here, it's
kind of the invisible character on Visual Studio Code is a tab character, okay?
So Go uses tab characters for indentation, not space.
I use the extension so every time I save it, it formats for me the code.
So I think if I do weird stuff like this and press save, the extension already removes
that, all that extra stuff.
So it's very opinionated language, like in the sense that it's very strict, it doesn't
give you a lot of flexibility to do stuff, it's just the only one way, only always use
tab for indentation.
Anyway, I hope everybody got Go lang installed by now, if you don't have it installed, let
me know there.
Anyway, okay, how do we run this program?
I'm going to open a terminal here for convenience, and you can choose whatever on Visual Studio
Code.
Let's choose command prompt for the sake of simplicity, and I'll trash the other one.
So basically you're going to say just Go, and there are different ways to run this program.
The simplest way you can do it is Go run, and then make.call the name of the file.
What this does is it's going to build, compile this, and in some place, temporary place,
and then we'll execute that program, that binary file, executable, and then after it's
completed, delete that file.
So because of that, you don't even notice there's anything in the current directory.
It probably throws it somewhere in the temporary directory for the operating system, and you
can see it says hello.
Now another way you can do this manually, you can go build main.go, and that should generate
the executable in the current directory with the same name as the file.
See main.exe because I'm on Windows, and I can execute with . slash main.exe, and it
says hello anyway.
So if you wanted to act like Python or any other language without you actually seeing
the file being built, just use Go run.
Anyway, I'm going to delete the file.
So every time you change the code, you have to run or build again, right?
Because it's a compiled language.
It's not interpreted.
Anyway, so everybody's comfortable with that.
Let's create an HTTP server.
So to do that, we're going to leverage the HTTP module.
So we can just say, let me delete this line here, HTTP.list, and you notice I'm using
the extension when I say ., it tells us all the possible choices out of this module.
So that's what's powerful about this extension.
If you're coming from another language and you don't quite understand or learn, you want
to learn all the methods that are available in Go without having to manually go to their
documentation website and everything, reading tutorials, you can just figure out by looking
at these auto-completions.
So I want the function to listen and serve.
And if I press enter, you can see it automatically imports from me at the top.
That's because of the extension.
Otherwise, I would have to do it manually go up there and add .NET HTTP.
I noticed it reformatted that before I had like this.
And if I wanted an HTTP, I would have to do it like this, right?
That's the same way.
But because Go is like strict about every time you save formats a certain way, it will just
combine them.
So if you combine them, it will just do it like this.
And notice I no longer use the FMT, so that's why I removed when I saved before.
So even if I remove it, I think if I save it, it's going to reformat probably.
Anyway, the listen and serve method here, somebody asked, how do you write a comment?
It's a slash slash like any C-based language, start up a server like this, okay?
If you're on Visual Studio Code, control slash, if you press control slash, it should comment
and uncomment.
Okay, this function here, if you hover over it, that's another feature from the extension,
it gives you the documentation for the function.
So if you read the first line, it tells you, okay, it's a function that accepts two arguments.
The first is of type string, the second of type HTTP.handler, HTTP is the module.
So inside the module, there's this type called handle.
So the first is going to be the, basically we can give a port to be very brief, with
quotes, colon, any port like 8080.
If you're using 8080 for something else right now, choose another number.
And the second argument here is the handler, and if you don't pass it, I think it will
be just nil, that's why we call it null value.
And it will just use the default one.
You can see the handler is typically nil, you see, read this here, in which case default
served MUX is used.
So that's what it does.
Anyway, that should start up the server.
So if you do go around main.go, it should do that.
And it, Windows is asking me, do you want to allow public and private, whatever I click
allows, it's kind of annoying every time I compile it does that.
I probably have to change my settings to make it automatically accept.
So annoying, but that's the way it is.
I don't know how I would act on Mac, if it would ask for permission as well.
Anyway, it's running, even though it doesn't see anything, it's actually running.
And to validate that, let's go to the browser here, see this one.
For the person just got here, you got to install, let me see, some people just got here.
So let's take a moment to let them know where to install go.
But those who just got here, I paste the link again, that's where you should install go.
So make sure to go to this page to install the Go programming language if you haven't
already done so.
Anyway, as I was saying, localhost or 127.0.0.1, 8080.
You can see 404 page not found, that means it's actually running the server, it just
doesn't have that specific endpoint setup to say hello, nothing there, but it's working.
All right, going back to the code, let me see this one.
For those who just got here, we just created a directory, we created the file main.go,
and this is the search code.
By the way, I'm using visual studio code with the extension go for visual studio code,
if you click the extension tab and look for go, install that.
And then going back, this is the file, I can run it in a terminal with go run main.go.
And to kill the service, control C, okay, control C to exit, obviously, there's nothing
going on here.
So let's make something more interesting.
How do we add an endpoint, like say get slash hello, and send some message back to the client?
Well, we're going to see, we got to call the handle func, okay, so HP dot handle func
like this.
And the argument is going to be the endpoint, so if you put slash hello, it will match,
if anybody tries to go to slash hello, localhost colon 80, 80 slash hello, no matter the HP
verb, it could be get, post, put, delete, whatever.
It will just hit this function that's passed as the second argument.
So the second argument to the dysfunction here is a function itself.
So you can, if you want to pass a function as an argument, just call the func like this,
and then just pass the arguments there.
But what are the arguments?
So you can read the docs, like I was comma here.
So it's a function that has the type response writer and a pointer to the request, okay?
So let's do that here.
So you just say func, it's pretty much always like this.
Usually they call it w, but you can call it whatever.
And in go, if you want to specify the type of the variable, you have to add a space and
then the type.
The type here is HP module dot response writer.
And then the second argument or parameter to the function is the request R, we call
it R.
And it's a pointer.
So you have to have a star.
Yes, there are pointers in go, just like C and C plus plus.
Don't be afraid though.
It's going to be okay.
And then the type is HP dot request, okay?
And it's a pointer.
So don't forget the asterisk.
I think the request, yeah, okay.
We got that right.
And then you can pass the definition between the open and curly and closing curly brace.
Somebody asked, does Go support hot reloading so we don't have control seal at the time?
Yes, there is a tool for that.
You can look it up, just make a search, how to restart a server when you change the code
in Golang.
Yeah, we'll tell you there's a tool for that.
I used that before.
I can't recall the name right now, but I just do a quick search and you can find it.
And pretty much just watch your files and just recompile and rerun it.
I like Nodemon in JavaScript world.
Anyway, we got that down.
Now what do we do?
How do you send a response back?
Let's make it easy.
Well, we got to use this parameter, the W, to write the response.
But it's a little bit harder than other frameworks in JavaScript, like simpler.
We have to do a little bit more.
So one way we can write back a response is if you call them the W dot, and you can see
there's some methods out of that thing, and we can say write.
This function could do it, but it receives an array, not an array, sorry.
If you're new to Golang, there are several data structure types, and one of them, you
can see the square bracket, typically you think of arrays, right?
But in Golang, when you see the square bracket and there's no number between the square brackets,
it's called a slice.
And in Golang, arrays have fixed size, but the slice is what has dynamic size.
So if you need something that changes over time, you want to choose a slice.
So it expects as an argument a slice of byte.
Now if you put a string like this, hello world, it's not really going to work, okay?
Cannot use hello world, because that's not a slice of byte, okay?
So if you try to go around that, let's see if we get a compiler or not.
Will I catch it?
Oh, I didn't save it, sorry.
Save the file first.
Make sure to save the file first, and then its catch cannot use hello, just like it did
in the extension here.
You need a slice of byte, yeah.
So you have to convert this to a byte, slice of byte.
So the way you can do it is just put a square brackets byte like this, and place the string
with parentheses, and that way it should work.
Yes, type hinting is mandatory in Go.
Depends.
It can infer the type, so for the most part you have to specify it, just like we did here,
okay?
Sometimes you can infer, but most of the time it's a, you got to see it.
Anyway, I put that there, so it converts the string literal to a byte, a slice of bytes,
and if I run that, I should be able to, I click allow on Windows, which is very annoying,
but it's just the way it is.
Somebody knows how to fix that, let me know, because I have to look it up.
I think somewhere in the firewall settings, okay, let me look at Firefox.
If I go hello here, see hello world is back to me.
Now one detail about the Hendofunk is it doesn't matter if it's get request, post request,
and that kind of sucks.
Let me see if I can show you here what I'm talking about.
Let me close all tabs.
I have this program to make HP request called postman that I can simulate a post request
for you.
Just got too many things open, but let me know if you didn't get Go installed yet, or
if you have any problems, okay, while I'm doing this, clear all, okay.
Let me show you postman.
This is a very nice tool.
If you don't have it, I suggest you install it to make, click plus.
So I'm going to change the verb to post, because the browser, when you say get, right, it should
be localhost 8080.
That's what the browser does when you go to the address bar, press enter.
But to simulate a post, right, method post, I can choose that there, and you can see send
it still.
I have to say hello here, sorry.
You see, forget the works, for post, it works.
So every single method is matching.
So that sucks.
That's what you want.
So let's change that behavior.
So typically before version 122 of Go, you couldn't do this, but now you can do get there.
Otherwise you would have to go to the R dot, I think, method.
You got to do a check that value to see if it's get, or post, or whatever, manually,
and then figure out what to do.
But now we don't have to do that.
You can just put get there.
Or you could have used Gorilla Mux, it's another way.
It's a package that a module that you can download that makes it easier than this.
Anyway, you could put get there, so it only matches slash hello with the get method, and
control C, go round main dot go again, allow, and let's check it out.
Oops, I didn't show you the code, did I?
Sorry about that.
So I don't know if I showed you or share my screen.
What I did was add a get here, space, before slash hello, on line eight, and it works now
in Go 122 and up.
If you have another version of Go, it might not work, so you would have to go and R dot
method check that value, if it's post, get, or whatever, and send a response accordingly.
Anyway, that's what I meant.
Going back to the, let me see post man again.
Now if I try a try post slash hello method not allowed, so it automatically gives me
an error, so I don't have that anymore.
So if I do get, now that works, says hello world.
Okay, great.
Now let's talk JSON.
Make it more exciting.
Going back to the code.
This is just plain text.
What about JSON?
Well, when we have a JSON API, we have to first set the header, content type to application
slash JSON.
So how do we set the header?
Well, before we write, you can say w, that's the thing here, for the response writer.
And by the way, if you hover over this, you can see response writer is an interface.
So it's, Go is not object oriented in the sense there's no classes.
So at the terminology, you got to watch out, like I would instinctively, I would say this
is an object.
You know what I mean?
But it's a response writer type, which is an interface.
So just trying to be careful of my words.
And the request here is a struct, structure.
It's a, basically it's a type request, but that in turn is defined as a structure, which
is like C language, right?
Very bare C language.
Anyway, use the w dot header, okay, and call it as a function like this.
And you should be able to do a dot set with the content type is string literal as a first.
And the second is the value application slash JSON.
So basically this would set the HP header content type of the value application slash
JSON.
Again, once again, you notice Go, usually the first letter of the functions is capital
lies, and the reason for that is usually in the modules.
If you have lower case, you cannot access the function from outside the module.
So if somebody is using the module from the outside, they have, you have to make the function
first letter capital lies, otherwise you don't access it.
Maybe if you're come from Microsoft C sharp world Pascal case, you're used to this kind
of thing.
Otherwise people might think it's strange.
And that's how you set a header.
Now let's send some JSON here.
Basically you can just change that to a JSON thing, like curly brace, right?
Let's say, now if you want to type double quotes there, you can escape it with backslash
double quotes.
Let's say that's the message property, and then backslash quotes, and then colon, right?
And then we have the value backslash quotes, which will be the message hello world, and
then backslash quotes, and finish off with the curly brace there, okay?
You can add space if you find it hard to read.
So basically this would be the string in a JSON format, and because the content type,
the browser will understand this as you're sending back JSON.
Somebody asked you to set up the header for each and every route, or is there a common
place we can set it?
Yeah, so I think you can add a middleware to always set it.
There's a catch all thing that you can set, so it will always set it.
But otherwise, maybe you can make your own, your helper function, or your handler functions.
Basically a handler function that you can always set something before, that in return
will call the function that's passed in.
You got to look at the docs, or maybe look into Gorilla Mux.
This is the very bare way of making the API, and if you want to fence your way, maybe you
might like better using Gorilla Mux.
Let me try to show you here.
Gorilla Mux.
This is what many people like using.
It's very similar.
Just adds a new functionality on top.
This is Gorilla Mux.
I'll send you the link.
It's basically the same.
You can see handle func, handle func, it just adds stuff like .methods, you can say .methods
like this.
See that?
Handle func, and then you can see .methods post, which is not available under the bare
one.
Let me see if middleware, yeah, there's middleware here.
I think even the bare, the default one has middleware.
Let's see if we have middleware here.
By the way, while we're at this question, let me show you how it can reference documentation.
I'm using the HP module, right?
How do you find documentation for Go?
Well, it's in the Go website, or you can just look it up, like hp.net.hp, and it should
go to this website, pkg.go.dev.
This is where they have the modules.
It's like a registry thing, or it's more like a proxy.
Basically this is the docs.
I'll send you this to you, and you can see, read about it, and here's the index.
If you want to find something like handle func as this one, see this one, click there,
and it tells you what it is.
Example, okay, you can handle func like this, and in the example here, they define the function
in a variable outside.
We can do that as well, and other stuff.
Let me see if they have middleware.
I don't find anything about middleware here.
So probably not as fancy as Gorilla Mux.
But there's a catch all, let me see.
If you do slash as the endpoint, that's the catch all that any route will match, I think.
If you do here, going back to the code, hp handle func, let me see.
If I do slash, I think that's the catch all.
It got confusing in the beginning as well.
You might think that's going to match slash, but it actually matches every single route,
I think.
Let me try to set something there to see if it works for you, and then we move on, just
out of curiosity.
Okay, I got my function there.
But notice I didn't type any semicolon, right?
Usually C-based languages need a semicolon at the end of every statement.
What's funny about Go is it actually needs a semicolon, but you as the programmer don't
have to type it, because the compiler will actually add it for you.
So that's something curious about Go.
Anyway, here I just want to set a header, and I'll just do X whatever, something here.
Just to test it out, see if it's doing anything.
If it doesn't do, just move on.
Anyway, so usually it would match all.
Let's see.
So if I restart my server, allow, and I want to observe that.
I'm going to use postman, but you can use the browser as well.
It doesn't matter.
Let me use postman.
Maybe I'll send you the link to postman, since I'm using so much.
Or it could be any REST client, even curl, if you like using curl.
By the way, that's the link to postman.
And if you open postman, by the way, you don't have to register anything.
Just click skip and go to the main page once you open the program.
Anyway, somebody said insomnia is better.
I assume that's like postman, so you can use that as well.
I don't care.
Anyway, I wanted to check post, hello, I want to check the response headers here.
I can see X whatever is there.
See that?
So it's actually working as a mirrorware.
So if I go to whatever, this one doesn't, we don't have it, right?
But if you go to post, hello, we got X whatever there.
And this year, all right.
And I noticed it might have wiped.
I don't know if it wiped the other one, because I don't see the content type.
I don't know why.
What's the body here?
It's not sending anything.
Oh, I put get, right.
That's why.
There you go.
Yeah, so it seems like not really middleware.
It's a more of, if it doesn't match that, I guess it matches that catch all.
So it's more like a catch all if you want to, if you don't match any of the routes you
specified it would just go to the slash.
It's not really middleware.
So I would look into Gorilla Mux for a better middleware solution.
Yeah, let's go to the code.
Somebody asks, what's the code like?
So this is the code.
Better just clarify, this is not really middleware.
It's more like a catch all route if nothing else matches.
For the middleware thing, maybe look into Gorilla Mux.
It's a better way.
Or build your own thing to match, I don't know, be very complicated.
Anyway, let's go on, that's enough.
We wrote JSON manually, but that's not what we usually do.
That usually comes from a database.
So let's take a step further.
How would we serialize, deserialize, within Go?
Let me just leave a comment here.
This is a catch all route if no other matches.
So here, I want to take this out and kind of make it like our own, like a few object-oriented
programming, our own object, right, or hash structure or dictionary in Python.
How do we do that?
Well, in Go, you can declare types and you can use structures, struct.
So if you have like a struct, like this is how you do it.
But then if you want to name this type, you've got to use the type keyword to, like, let's
name it, let's say we're doing, let's say we're doing a bookstore and I want to keep
track of send back books.
I want to make a type for book and that type is actually a struct.
And this is one of the primitive, the built-in stuff.
So a book has, like, a title, right?
So we can say title here, like this, space, and that's a string.
That's the type, okay?
So we got to define a struct, the curly braces, the name of the property, and the type follows.
You can add more stuff, maybe you want to give an ID, right?
Usually there's an ID from the database.
This ID here, now in Go, there's different data types for a number, not like JavaScript,
where's just one.
So there's int, there's float.
So let's make this an int to make it simple.
And notice I put the first letter capitalized because that's what we usually do in Go for
things like that.
Like I said before, the case matters usually for something outside the model to access
it.
And you might be asking later, okay, the JSON is usually lowercase.
How do we change that?
I'm going to let you know in a while, in a little bit.
But anyway, we make the type there, struct, and then you can go here, let's, how to declare
a variable.
Where one way is var, space, give it a name, let's call it, call it book, okay?
And then the type is going to be book.
And then if you want to, you can put equal sign right away, or you can do it later with
book equals.
It doesn't matter.
Okay, like if you do it right away, you would have to pass like a struct here.
Let's initialize it with kind of a lonely struct.
You can say, like, let's say, it's like this.
ID would be one, that'll book title one, like that.
So basically, the right-hand side, you've got to have something, if you want to specify
like a structure literal, you have to say the type here, followed by the curly brace,
and then the values in order, as they are typed here.
If you don't want to type in order, I think you can do like this, and like this, okay?
So typically, maybe you want to do it, break it into multiple lines.
And it's going to complain here, because you don't have a comma.
So if you have a multiple lines and go, it strictly wants you to type a comma.
And there you go.
It looks like a lot of like a dictionary in Python, or object in JavaScript, right?
Yeah, just a little details, you've got to put the name here, and the comma there.
And then here it's complaining because I'm not using it.
So in Go, if you don't use a variable, it's a compile error.
If I try to run that, sorry, let me save first.
Save first, and I try to run it.
It's going to complain that I didn't use it.
Okay, so I've got to use it somehow.
Let's go here.
I've got to use that here, right?
But how do I do it?
Because this is not string, right?
How do I make that a string?
So that's why I've got to use the JSON module.
So we've got JSON here, and we've got some methods.
Okay, so we've got Marshall, we've got un-Marshall.
Let me see what's un-Marshall.
The Marshall parses JSON-encoded data and stores result and value, whatever,
whatever, what's Marshall?
Let's see Marshall.
Marshall returns a JSON encoding of v.
And you can see here v is of any type, or usually called interface, empty interface.
So that's the one we want to use.
Like this, it's like the serialized, serialized methods in other languages.
So you want to call that and you pass the book thing, and
that should give you back the stuff so you can pass it here.
Let's see what happens.
Let's just remove this here and put it inside.
So it's going to complain, I think.
So too many arguments, whatever, let's see.
Another way to declare a variable in Go is with the colon equals.
So let's call it encoded book colon equals.
So colon equals here is another way to define a variable inside a function.
Instead of you manually typing a bar and then the name and then the type.
Okay.
And this is complaining because this Marshall function, if you notice the signature for
the function, you can see there's the v any as the argument.
But the return type is actually not one thing, but two.
So it's a tuple.
So we have a slice of bytes and an error.
So that's very common in Go.
They don't have like proper exception in that kind of mechanism.
It's all done through these, usually the functions would return two things.
One is the value and the second is if there's an error.
So this would actually have to return two things.
The second one would be the error like that.
And you have to check if the error is not nil,
meaning if there is an error, right?
This is how you do if states by the way, no need for parentheses.
In that case, you can log fatal, code and
Marshall, the book or whatever, oops.
And then you can pass the error here like that.
And I forgot my curly brace.
That you need and it's complaining log doesn't, doesn't exist.
You got imported the top.
If I save it, it's gonna import there.
And finally, it's complaining that I'm not using that.
So let's try using that here.
And if you remember right requires a slice of bytes, so that's correct, right?
So if we run it again, we should finally be able to see it.
And by the way, I don't know, I don't wanna say hello.
Let's say books slash one.
How about that, and I'll save that and rerun it.
I changed the endpoint to be slash book slash one.
Let's go here.
Where's the browser?
Share.
Oops, not that one.
All right, where's my browser here?
Going back here, localhost 8080, and we're gonna say book slash one.
If I inspect of the DevTools, the press F12, network tab.
I'm using Firefox, but Chrome should be the same network tab.
I can refresh and monitor it if you click all for the filters.
You should see this one.
And the response, if you click raw, it's just raw, taxing, right?
With the JSON format, and notice the capitalized ID and title.
And if I look at the headers for the response, request, let's see response.
I see content type application JSON, and because of that,
the browser is smart enough to create this live view of the JSON.
Let me zoom in for you.
And it's exactly what we had there, right?
Now, I've got to be asking, hey, I want this to be lowercase.
Can we do that?
Yes, we can.
Let me show you.
So it's kind of funny how we do it and go.
We got to add a tag to the struct property.
It's kind of weird, but just the way it is.
So you would go to the struct that defines the type that you're serializing,
the serializing, and you add a third thing here, a back tick.
Okay, it's called a tag.
Okay, you can tag this property.
And you can pass JSON, colon, and ID.
So you have to type JSON, colon, and double quotes.
And the name of how you want this to be output as it's converted to a string
in JSON format.
Don't forget to close the double quotes.
And it's a back tick, by the way.
So this would tag this property with that.
And why does it does that?
Who is doing this stuff of changing to lowercase?
We got to do the same here, like this, okay?
Back tick, JSON, colon, double quotes, title, that's how we want it to show.
And then quotes and close that.
Now, who is doing all this stuff?
Well, it's the package or module encoding JSON.
This one here, if you click here to see the docs, we will be able to see it.
And in the docs, it tells us about that.
I want to show you, so don't just take it for granted.
So let's go to the docs here.
We'll go jump to JSON.
Where is it?
Encoding slash JSON, I think.
This one, I'll send you the link.
Somebody asked, damn, this is too complicated.
That's, I mean, go is supposed to be simple, right?
Anyway, let's look at Marshall here.
That's what we use, right?
So if you read the docs for Marshall and look for tag, something like that,
where is it?
Okay, here.
The encoding of each struct field can be customized.
Start on the JSON key in a struct fields tag.
See that?
So this is what's doing that stuff.
So when you call the Marshall function, it will look to see,
does this property from the struct have a tag?
If that is the case, I'll use that to produce my property name.
Okay, so that's where it's coming from.
I'll send you the link direct.
Anyway, going back to the stuff there, after adding those tags,
let me make sure I'm in the right JSON API.
We got the tags here.
So we can change this from upper case to lower case.
Save that, run the server again.
And allow, share the browser,
go to localhost88.com, slash book, slash one again,
and now it's lower case.
Okay.
And that's because the JSON module Marshall function,
as it goes through the structure,
it will look there's a tag.
Therefore, I'll use that name for the property instead of the original one.
All right, somebody validated as well, got it working.
Yeah, so that's the way it go up, go.
Now, let me teach you a way if you're tired of writing it out.
You want to be just like Python or JavaScript,
where you can just spit it out without declaring the structure.
We can do that with what's called an empty interface,
what they call any these days and go.
So we would go here.
If you don't want to use this thing of the empty stuff,
you can go, let me show you empty interface like this.
If you want to make like a map or object or hash kind of thing,
and go, they call it a map.
It will be like this, a map that takes a string property
and it produces something.
That's something if you put interface like this
with the curly braces empty,
this is called an empty interface, which is basically any.
You can also type any there, I think it works.
So think of that as the any type, it's whatever.
If I do that, that's the literal thing.
So in this case, I can make, I think like this.
Let me try if it works.
Let's see if it's going to work.
And then put that in a variable, book to colon equals and like this.
Undefined.
Oh, I have to put like this, right, because it's a string.
And yeah, and let's try using book to here and see if that works.
Let's try book declare now use, you see, go kind of, I got to comment this out
because it's not used and using this way, I don't have to declare a struct.
Right.
Let me share the browser.
It works the same way.
You can see book title to appears.
Right.
Obviously, I could have named my fields lower case.
So I changed this here to ID, lower case title, lower case, save it restart.
And go back to the browser.
And it's working lower case.
Okay, so this is a different way less structured.
If you use the, it's called the empty interface.
Basically, this is a map, which is like a dictionary in Python, or objects in
JavaScript, Ruby hash.
So the brackets, this telling you that this property value has to be a string.
And that the value of those properties like this right hand side of the colon is
whatever, empty interface.
If you put strictly put in here, they could also be a string.
If you strictly put in here, they could only be ends, right?
Give me an error.
This has to be an end.
Otherwise, if I want any value here, I put either any, I think that works.
Or the so-called empty interface.
Like that.
So if you like it this way, do it.
Otherwise, it's usually structured like this with the type, whatever struct, right?
That kind of stuff.
Yeah, let me know what you guys think of Go so far if you're new to the language.
You like it, you don't like it, sucks.
Let me know in the comments.
Anyway, that's how you pretty much go about doing the API.
And obviously, this is not going to, it's going to come from database.
So you'd have to look up how to use the driver for Go.
Just look up in the docs.
They have a database driver module, and they will tell you how to use.
Just import the driver and connect to the database with a string.
Let me see if I can show you an example through the browser since we're out of time.
Go line connect like MySQL.
Let's see this one, this one.
This is the official one.
So it's using MySQL.
So they're using this Go MySQL driver.
So import like this.
I'll send you the link if you like MySQL.
I use Postgres usually, so I would have to use another module.
Basically like this, they create a, they call a config, pass the parameters,
and then they open the connection, and eventually get this db object.
I think you can query, scroll down.
Let's see db.query, I think.
Yeah, db.query, and then you put the query and do all this stuff.
Once you get, this is taking like an array or slice of album.
I always say array, but in Go you got to say slice if you don't see a number between the square brackets.
And then they go over with a loop like that with the four.
Actually it's called four here, but this is actually a while loop.
In Go there's no while loop.
They use the keyword four for all kinds of loops.
So if you omit like the, you know, the for loop traditionally has initializer, condition, increment, increment.
So if you omit the initializer and decrement, increment only has a condition that becomes a while,
so you can omit, and it becomes for whatever condition here while that's true, do this.
And they're doing the scan.
Basically they're taking the values from the database and storing in this object of album here that they remember is the struct.
See the struct there.
And that's how we would do it.
Somebody asked, do we have an ORM for querying stuff in Go?
Probably they have.
Go line, go ORM.
You can look it up and try it for yourself.
But I don't know.
People in Go, they'd like, they claim to be one of the simplest possible.
They don't want, they don't need to use whatever external things.
So I don't know.
Probably there's a good one.
I think there might be good ones there to try.
If you have a particular one that you found, let us know.
Anyway, try it out later.
And going back to the code just to finish it off.
That's how we pretty much go about doing that.
You can, obviously you don't have to write the functions here and all in one file.
First of all, you don't have to write the function here.
You can isolate that in a different thing.
You can call like funk handle single book like that.
And if you want to give a name to the functions after the funk keyword,
and you can put it here, handle single book,
and you should be able to use it from there.
So in Go, when you declare things here on the top level, it's called the package level.
And that's kind of, it's kind of like global in other language, global scope.
But be careful if you're using this defining on the package level with the lower case,
and you want to make this function available to people outside the module,
you have to make it upper with the handle H capitalize.
So there's that.
So be careful.
If you see it not working, that's why.
And it couldn't go on.
You would create many handle functions like that for every single endpoint.
And obviously you don't have to do it in this single place.
You could call function to do that for you, right?
You can set up endpoints, whatever.
And that function, you could put in another file, right?
Setup.goal.
And as long as you put that in the same package main, for example,
if it's in the same package here, this function that you define here,
sorry, funk setup, it will be available on this other file.
You can just call setup.
As long as when go goes through it, it sees that setup here is declared in the package level.
So it's going to go in a main package.
So whoever's using is from the main package here.
You're assigned main package.
If you call the lower case, it should work.
However, if you have a different package name and you're trying to reference the function from another package,
you have to make the function capitalize so that the other package can use it.
And then from the other package, you would call these the as capitalized.
Okay.
So let me try to just finish off here.
So setup.
There'll be HP and the funk.
Let's just put a hello here again.
Say hello.
And then we could put funk.
Say hello.
Now is forget the signature was it a W and the R.
And you have to put the types and it's a pointer here.
W HP response writer.
And the second pointer to HP.
Oops, HP request.
And then let's say, let's just send a message.
Another way of sending the right is FMT.print.
There's another way here.
Let me show you print F.
This is yet another way to send back a response.
Hello world.
And that requires FMT.
Sorry.
It's lower case reports FMT.
Not HP.
I think it's going to.
And this one, what did I do wrong here?
Hello.
The string value.
That should be okay.
I put F.
Oh, sorry.
F print.
You got to have F print.
That's if you don't like this, just put write with the byte, whatever, right?
If you don't like that, same thing.
You don't like that.
I'm just showing you a different way of doing anything.
So that's F print F with the W there.
And because this is here, it goes there.
And because setup is defined the same main module, I can call it from here like that.
And it should call that function define the slash hello.
So let's see if I don't have an error.
Oh, no, undefined.
Why?
Why do I have an error?
Because when I say go run, I only pass main.go and not setup.go.
I only pass all the files that I'm using for the project.
So you have to add setup.go there.
That way it knows about it.
Okay, now it's working.
Let's go back and I'll look at my browser again.
I'll go to slash hello.
I expect that to work.
There you go.
Okay.
And that's it.
You figure out your organization structure, you know, read about how people like organize things and go.
But this is mostly have to do with the package level.
You got to understand there's package level scope.
And as long as they're in the same package, you can access just by calling it.
It doesn't have to be in the same file.
And like I said, if you have a different module referencing some function in another module, make sure to the function name that first letter is capitalized.
Otherwise it will not be able to access it.
Okay, I think I conclude this lecture with that.
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? ๐๐
Consider a donation to support our work: