Are not uncommon thing. You might have to do is provide some sort of
web interface be it, an API or an actual HTML interface to a
database. And I'm going to go through a simple example here where I
provide access to sqlite database, using the database SQL,
functionality to provide a web interface and then I'll change it
from Just producing text to producing Jason to make something that looks a bit like an
API. And then I'll actually add methods to it so we can update the database and
see how it operates.
It's so first of all, I've prepared a fairly simple program which allows us to access a
database of scientist names and let me just bring up that database we
see what it looks like.
So there's a number of scientists names in here with different field values. And within the
program, I have defined an API or web-based API, which I'm going to use
to access it. So let's first of all, start with main, I just
connect to the database in a very familiar way which is to use SQL to open from
the database package and that particular database file and
then I'm actually storing the database handle if you like in this
database server struct, which is defined here. And
And the moment that's all it has but it could be many other things in it and
I'm going to use the net/http package to start
serving HTTP on port. 8080 on my local machine,
and there's one route here which is / API
and it's going to call a method value. If you remember earlier in this, I talked about
method values. Well, DS, which is a database server has a
method, which is here API, which has the right signature
to be handled by a
Little funk in net/http so I can just call it in there. This is the method
value here. And so when anyone calls makes a
an HTTP request, the / API on here, will end up being
sent into this function here. And this function has a couple of parameters. One is
this response writer which is where you send your response back to the user. And there's
a point to the request itself, which came in which is already been passed
and the API wanted to find is pretty simple. It allows you to look up somebody by
last name and get their first name.
So first thing I do is I pass any form values so that I can pass. The
last thing I'm going to expect there to be a last name, so last
equals something and if there isn't, I'm going to throw a bad request error
back saying it's missing and if there is I'm going to get the last
name and then I'm going to go to the database and pull out the corresponding
record. So let's go into here and I'm going to say I'm going to use the database
handle which is in the date of this database server. And to do this
query, get the
Name where the last name equals that and I'm using here a
placeholder and passing in last as a parameter to query.
And if that goes wrong, then I'll say there's a problem and if not, I
will get the first row. I'm assuming they'll only be one row. Of course, there
might be more than one being this case, it's Unique scan out. Just the
first name, that's all I've asked for here. So I can just do a scan like this,
and I'm just going to print it out. I'm just going to say this person has this name or if it's not
found. This is what
Happened. So this will end up returning a 200 because there's no error and this
whole thing right now is a working server which can talk to this database. So
let's just make sure it builds
That looks pretty good and run it. So if you look at this
last thing here, listen serve, it's now sitting waiting for
any requests on port 8080. And what I can do is go over here
and just do a curl against it.
So 404 not found because there's nothing on /. If I go to the
API and going to get an error missing laughs, let's just get the
headers out of that. You're going to see there. It says, 400 bad request because that was the
thing. I told it to do up here, which is if there was no last then give me a 400, bad request. All right,
let's see what happens. If we ask if somebody who isn't a database, let's last for Ada
Lovelace. So we're going to go last equals
the place and there you see Lovelace first name is Aida so it's gone.
It's found the thing is done. This database query is got Rose, paused it and return it to the user.
And it's really a very small amount of code to be able to do that. Let's just do one more. Let's try one where
the person is missing. So I don't see John
Logie, Baird in here and bed not found. So that was the other
branch of this here. So that's a basic hook up of a web-based
interface to it to a database. Now, it's just, I'm going to go ahead
now and change this obviously, textual responses aren't that great. Let's actually
She return a Json response instead, so I've been much
nicer if this API returns Json rather than returning a bit of
text. So, I want to be a bit more structured and that's actually pretty easy to do. Go
has an encoding /, Jason package which will do most of the work for you. So what
I've done is I've modified the program here so that it now reads all the fields from the database to
make it a bit more interesting. Stores them in a structure, I'm going to use an anonymous
structure since I don't need to name it and then Marshalls that into Jason and writes
it out. So just take a look at how that's
You just import encoding/json here
and this is all the same. I'm not modified this query.
So that rather than just getting the first name, I get all the fields. And
I've now when I ask you find the result, I've made this result
variable here, you notice, I'm using Anonymous structure because I don't need to
type red and just contains all the fields that I'm retrieving the ID first name
last name and whether they're alive, which I then scan in.
Unfortunately, I have to scan them all in like this.
Is that the scan interface won't let me easily scan it into the structure, but it still
works. And then I'm going to use Jason Marshall, which is going to take
that crate it into Json into this thing. Jay obviously if something goes wrong with
that that's an internal server error. We should talk about that and then I'm going to write the Jason
out to W which is member is the response writer and that's it. So
that's the change to make it work with Jason. So let's just
build that guy.
And run it. Okay, so that's running
and we'll ask it to look up, somebody called Lovelace
using their last name and I'm piping it through Jason PP. Just get some nice, stretch it out bird
and there you go. So that's now query the database created Json output in much more
structured format. So we're getting close to now to something which is an
API. The big thing we haven't got right now isn't any distinction between getting and putting.
So what I'm going to do is I'm going to modify this so I can actually update the
Race by adding new people to it using a post. So having turned it
into something that provides Jason. The last step is to make it update the
database to make it into an API that actually does something useful. So what I've gone ahead
and done is modified the code, so it looks at the HTTP request
methods, see whether it's a get or a post. If it's a get then it's going to do what it did before
and look up someone in the database and return their details. If it's a
post, then it is going to go ahead and add that person to database.
And for a post, we're going to have a first
first name and a last name to be inserted into the database. So I did a little bit of
refactoring, let's just take a look. I took out everything that was doing
the get from the database, the query here and gave it made it into a function called
get and I created a new function called Marshall.
And what Marshall does is it writes some arbitrary piece of
Json to the response writer. So we're going to use that a few different places to write different bits
of Jason. I also added a Boolean called success to the
result. So I could say whether something was
For now. So all of my Json responses will have a Boolean success or not.
And so the simple get a pi now is handled by the
API function. So everything has a last name. So I checked the last
name first, and then I go in and look at the request method, never forget, I do this,
get thing. And if it's a post, I do the new post item
and the post function, it has to get the first note, we need the
first-name and make sure that's there and then it's simply doing an insert into
with these
He's placeholder elements for the first name and the last name. Let's tidy that up
error. Obviously, if something goes wrong and then just return a success. So, let's return a
very small piece of Jason, that just says success, that's what this Anonymous struct here, will
do. So let's make sure that builds.
Looks good. Okay, now let's go ahead and look someone up in
here. So let's look up.
Ada Lovelace. Again, just look her up.
Okay, there she is. It gets her details. Look up someone who's not there. I'm going to look at Mary
Somerville.
So that's not successful. She doesn't exist and obviously you could have a different message in here.
So let's add Mary Somerville. So what I'm going to do is I'm going to turn this into a post.
And I am going to say first name, Mary.
And so that's that's been added to the database and let's just check the she's there. And
there she is. She's been added Mary Somerville, and that's what particular ID, and obviously, we could go
into the database. We have a look at the record as being created within their. So, as you can see,
is not a lot of code to start building up an API like this. And
obviously, there are many other things you can do to around templating
because go have a nice template you Library. So you might want
To have templated responses in some cases when it's HTML. But
basically between encoding/json database, SQL, and net/http. Those
three packages, you can build a fully featured API server, that
talks to a database with really, no problem at all.