All right.
So now that we've seen how to authenticate ourselves with API providers and how to start making server
side requests using Axios, let's interact with this REST API fully, and see how we can make the whole
range of requests, including POST, PUT, PATCH and DELETE.
We saw from previously that we can make GET requests using Axios by putting it inside a "try-catch block"
and inside the try block, we use the method, axios.get() and then we can pass in a URL and also some
piece of config, or data, or headers, or authentication, whatever it may be.
There's a whole bunch of settings, and I know this because I've read the Axios documentation.
If we take a look inside the example, you can see this is our GET request.
Now, as you can see from the documentation, there is an alternative way of calling Axios by chaining
.then to the end of the axios.get() method, we can also chain a .catch() and we can also chain a
.finally() as well.
If you remember from previously when we covered this in the JavaScript sections, what is the difference
between using a method like this and then chaining the .then() versus marking the method as async and
then using the await keyword before we call something like axios.get() .
Both of these come from the JavaScript Promises API, but they work slightly differently.
The .then() method gets triggered once this promise gets resolved.
So then it will wait until it's done and then it'll look at the .then() and inside the
.then() we can have another promise-based method and we can keep chaining these to happen in order.
The alternative is the more modern syntax which was introduced in 2017 as a part of the ES8 upgrade
to JavaScript.
And this is formed by the async and await keyword.
What happens in this case is we have a particular function and this function is marked as asynchronous
by having that async keyword before it, and then we can have the name of the function, for example,
get().
And then we have our curly braces,
and then inside here we can have some sort of process that happens asynchronously,
a nd all we have to do is mark it with the word await.
What this says is wait until this process is done before continuing to the next line of code.
And the nice thing about this style is that it kind of makes our code look as if it is synchronous code.
It's run line by line only.
Once this line of code is completed do we continue to the next line of code,
whereas, with the .then() syntax, it can get a little bit hairy when you're trying to debug it, especially
if you have lots of things chained on and you get confused,
"What is the order of things being called?"
Even though both of these methods are documented in the Axios documentation, I personally recommend
using the more modern syntax as I have been showing you in the course of using async and await rather
than using the .then() syntax.
But you can do exactly the same thing with both types of syntax,
essentially it is just a choice.
Maybe developers working with JavaScript for a long time already familiar with .then() and they don't want
to learn something new or change their practice,
but because we're learning this from scratch, I recommend using the modern syntax. We've seen GET,
but we need to cover the rest of the HTTP protocols, including POST, PUT, PATCH and DELETE because
for an API to be fully RESTful it should be able to handle all of these different routes.
So let's first take a look at how we can make a POST request using Axios. With the axios.get() syntax,
we have essentially only two optional parameters.
When we write .get(), we have the URL as the first parameter and then we have the config object as
the second parameter.
But when it comes to the .post(), we have an extra one in the middle which is called data on the Axios
documentation, but I'm calling it body because I think it makes a little bit more sense because that's
essentially what it is.
It's the body of your form data.
So maybe you have something called Username and you set it to some sort of value.
You have another one called Password and you set it to some sort of value.
This is the body of the URL-encoded data that you normally get from your HTML form, and that is what
you would put in here to be sent over when you're making the POST request. And similar to with GET,
you can also add different configs into this third optional parameter such as the headers
if you want to do authentication, using basic authentication.
And as always, you can find all of that documentation in the Request Config part of the Axios website.
Some of the parameters such as URL method, baseURL, so you can also format your requests like this
in the config instead of putting it at the beginning of the GET method.
You have things that we saw such as headers, such as the authorization header
when we're working with bearer tokens, you can pass parameters in the config, you can pass over the
basic authentication as well as a number of other settings. If you wanted to move on to PUT requests,
so remember that a put request provides all of the data that we want to update in our back-end.
So for example, if you have some sort of data, you have to provide everything and it's going to replace
your entire entry with whatever it is you
pass over in the put request.
The PUT method with Axios looks pretty much identical to POST,
apart from the fact that it's axios.put().
And similarly, we also have our PATCH request, which means that you can provide any bit of the data
you want to update and everything else in the resource stays as it is.
And finally, we have our DELETE method which notice in this time again only takes two parameters the
URL endpoint and also any config that you want to pass over as a JavaScript object.
This is the theory and you can explore more of it in detail by looking at the documentation.
They've added some simple examples such as a POST request or a GET request, but they've also got all
of the other aliases such as axios.delete(), or axios.post() or
axios.put(). And notice here, the parts which are optional to these methods are enclosed in these square
brackets.
For example, when you make a get request, you can simply just pass the URL, but optionally you can
also pass a config object.
But with the post request you actually have the URL, but also two different optional parameters the
data you want to post and also the config object.
So take a look at the documentation whenever you get stuck.
And also take a look at the slides from this lesson in order to complete the exercise for this lesson,
which is 5.5 REST APIs. Download this from the current lesson, extract it, and open it inside vs code.
First things first, install all of the node modules using "npm i".
And once you've done that, the second thing that is really important to do is to go into the solution.js
and go ahead and replace this empty string where it says, "yourBearerToken", with your very own
barrier token that you obtained in the previous lesson, where we covered this in detail.
So if you skipped it, be sure you head back because this is important for everything else to work.
And once you've pasted your own BearerToken in there, then I want you to go ahead and start up the
solution.js using nodemon. And then you can go over to localhost 3000 and you'll see our very simple
website.
The idea of the website is we're able to get secrets from the Secrets API by typing in the id of the
secret. So we can hit GET, and it will give us that secret with that particular ID. And the default secrets
go all the way up to number 50.
Now number 51 of course doesn't exist, but you can use the POST route to create it.
So let's add a secret of mine,
"Despite learning surfing for over 2 years, I'm still really bad at it."
It is a little bit embarrassing, but apparently it's one of the hardest sports, so I'm not going to
be too tough on myself. If I go ahead and add the secret and the score.
I don't need to add an ID because it will be automatically created in the POST route as per the documentation.
So let's go ahead and hit POST, and we get back the item that we just created.
So now if we try that GET route again and put in 51, you can see we now get back the secret that we
just created.
Let's say that we wanted to change this by making a PUT request,
we can specify the ID of the secret that we want to change, and then we can change our secret or change
our score,
but remember, with PUT request, we have to provide all of the data.
Let's go ahead and just change the score.
So I'm going to keep the same secret.
I'm going to change the score from 3 to 8.
Let's say I'm increasing the embarrassment level.
Let's go ahead and make the PUT request,
and you can see now what we get back is the changed secret
and the score has gone up.
And we can verify this again by posting to the GET route on ID 51.
Now, we can make a PATCH request which remember, you can simply just change one thing.
You don't have to provide all of the data.
So if I change the score back down to 2 and hit up the PATCH route, then you can see we're getting
back the secret with ID 51 and the score is now changed to 2.
And if I check this again, you can see it's exactly how we would expect it to.
And finally, I'm going to hit up the DELETE route to delete this item.
So hit up ID 51, hit DELETE and hopefully we have it deleted successfully.
And if we check the GET route for that ID again, it is no longer found because it has been deleted
from the server.
So this is what we are building and you can of course test that by going to the solution.js,
adding your bearer token from the previous lesson, running it just as I have done, and then going
into the index.js.
And then again first adding yourBearerToken,
because without that nothing else can work.
And then take a look at the first GET route,
I know that this is a POST and that's because it's linked up to a button in the HTML, which is in a
form.
And so the way that this website works is we've got a content area which takes a variable in the form
of content that injects anything that you pass it into this area using
EJS.
If you don't remember anything about EJS, be sure to look back on the previous module where we covered
this in more detail.
And then we've got three inputs into our form the ID, the Secret, and the Score.
Some of these are optional for some of the different routes.
And then we've got our five buttons, the GET route is this first button which will submit the form.
It will have a formaction of hitting up this particular route.
So previously in forms, you've noticed that we add our action up here and we have our method up here
when we declare the form.
Now, one thing I wanted to show you is that you can also add the action in the submit button itself.
So this way, even though we have five different buttons, the form is going to be submitted to different
routes depending on the formaction.
So the first GET button is going to hit up "/get-secret", which if you take a look inside the index.js
is this first POST route.
And then we've got all of our other ones "/post secret", "/put-secret", "/patch-secret" and "/delete-secret".
So we've got five different routes and even though it's all in the same form, it's all going to make
a POST request because we have to pass over certain pieces of data like the ID that the user wants to
get hold of from the GET route or the secret and score that they want to post into the POST route.
But they're all going to be hitting up different parts of our back-end.
And your job is to make sure that those back ends work exactly the same way as you saw when we ran the
solution.js.
Take a look at the first GET route.
It's got a lot of the Axios code that we went through in our lesson today, and see if you can use the
Axios documentation as well as what you learned in the lesson today, to make all of the rest of the routes
work.
Now, some of this might require a little bit of tinkering, a little bit of thinking, and probably a lot
of things going wrong,
but that is how programming works.
Give someone a program, frustrate them for a day, teach someone to program and frustrate them for
a lifetime.
The frustration is all a part of the joy and you will feel so much better about yourself once you overcome
all of those frustrations.
Pause the video and give that challenge a go.
All right, let's walk through the solution together.
Making sure that you've used all of the documentation and everything that is at hand to help you,
the first thing we're going to do is to paste in yourBearerToken, which you should have obtained
from the previous lesson.
Next, we've already got this GET route that's sorted, and it's a good place for us to be able to see
and remember how to make our Axios requests.
So remember putting it inside a try-catch block.
Once we get back the result, we can tap into the data through result.data and we can turn it into
a string using the JSON module and then pass it over to the EJS under a variable name called content.
Now, if there was an error, then instead we can send back the error.response. data, which
is going to be the error message from the Secrets API and we'll be able to log that into the content
area as well so that we can diagnose what's going on, but also tell the user if they're doing something
incorrectly.
The first thing we have to do is to get the POST route to work,
and as per the Axios documentation, it's as simple as simply writing axios.post().
This uses the .then() chaining method, but you can also see an example where they actually use the
axios.post() and essentially, it expects a possible three inputs.
One is the URL, the next one is the actual form data.
And finally, any configs such as headers for authentication.
In our case, we've got again our three sections, we've got our URL,
so we know this by checking the Secrets API documentation. In order to POST to this API,
we hit up the /secrets route and this is the example URL.
So it's the baseURL plus /secrets.
Our API_URL is already listed up here and our config for authenticating ourselves is also formatted
here.
All you had to do was to add in yourBearerToken to be inserted here and we can use this as one of
the config options to get access to authenticate with the Secrets API.
Now that we've formed our full URL which will end up looking like this,
alternatively, you could have just typed the whole thing in, but this is a little bit more concise.
The next thing we pass over is the data we want to send.
So in my case, I'm simply just tapping into the req.body because what the req.body
is going to look like is it's going to be a JavaScript object,
so curly braces and then it's going to be based on which of these inputs were filled in and what their
names and values are.
Now, you'll notice that I've very helpfully made the names the same as the expected Request Body names.
So we have a secret and we have a score.
So the secret is obviously the text for your secret, and the score is your embarrassment score.
And we get hold of those from our form.
In this case, when the user is making a POST request, they're going to fill in those pieces of data
and our req.body,
you can also console.log() this, of course, as always, it's going to look something like this.
The secret will be whatever they typed
and the score will be again, whatever they put in there.
So this is what req.body will look like if they fill in both of these parts.
And as always, it's a good idea to verify this yourself, but this is what it looks like.
And then this object is what's going to be put into here as the data that's going to be posted.
So now that we have our URL added, Number 1, we have our data added,
Number 2, the last part is simply the config, which is just the part of the code that we need in
order to authenticate ourselves with the API because as the documentation describes, it requires Bearer
token authentication, which you know all about because you did the last lesson.
Now we have our three parts to our axios.post(),
then we use the await and async syntax to say that we should wait for this process to complete.
So this is a promise,
and once that promise is resolved, then do we go to the next line.
Because at that point we will actually have a result and we'll be able to tap into the result.data in
order to send over to the
content variable inside the index.ejs. And this is what it would look like on our front-end, adding our
secret, adding our score, sending that over as the body to the Secrets API and we get back the secret
that was created.
And you can see this when you look at the documentation for the API, this is what we need to send over
as the data or the body of the request.
This is the endpoint we need to hit up and this is an example response when everything went correctly
and we simply put the response in as a string into this area through that content variable.
Now, let's look at the next two routes, the PUT and PATCH because they are very similar.
And one thing that I've added into the starting code to hopefully point you in the right direction is
the fact that we need this ID that comes in through the req.body.id because it is one of the
inputs for our form.
So when we submit the form, when we hit the submit button, we can tap into whatever the user typed
into that input area and we need it because if we look at the documentation, you can see that we have
to add the ID of the secret that we want to update as a part of the URL parameter.
That way the API knows which secret you want to update and this is what the full URL would look like.
In this case we are using axios.put() and axios.patch() which works pretty much the same as POST.
And we know to use this because firstly you took the lesson, but also if you look at the Axios documentation,
you can see that they have the same requirements pretty much as the POST method.
So here we've got the request URL formed by the baseURL plus /secrets/, and
then we insert the searchid, which is whatever the user typed into that field over inside here.
In addition, we've got the req.body, which is whatever it is the user wants to update, and
that is whatever they typed inside here and here.
And these will come over through the req.body,
and again, as previously they will be a JavaScript object which we can then pass to the API.
And finally we have the config which contains our authorization headers and we can make this request
and when we get back the result.data, we turn it into a string and pass it over as the variable content
into index.ejs.
And also similarly, any errors from the API also gets shown on the front-end.
So that way if we try to update something with an ID of 52 which we know doesn't exist because we haven't
created it, we get an error from the API telling us what went wrong.
Finally, we have the DELETE route, which is /delete and we again provide the {id} of the
resource we want to delete.
This time there is no body to pass and if you look at the Axios method, you'll also see this only takes
two parameters the URL and the config.
That is going to be the URL that is formed of the baseURL, the forward slash secrets plus the ID that
the user typed in to the input box.
We add the config to authenticate and authorize this operation and we get back some result.data if everything
went right, and an error.response.data if something went wrong. There you have it,
those are all the routes for a REST API and we've now managed to tap into each of them by looking at
the documentation for Axios and also the documentation for the API.
As I say, whenever you work with a new API, the documentation is your friend.
You really want to read through it and understand what's going on, at least with the endpoints that
you want to work with in that moment,
because if you don't and you don't understand what are the requirements or what you need to send over,
what are the key values, what is the URL, what kind of response you get back then you might end up
with weird errors that you have to try and debug down the line and it gets all a bit more hairy.
So my great tip is whenever you work with an API, spend some time looking at the documentation. Don't
just jump straight in, it will save you time down the line. And hopefully, there was sufficient frustration
in this exercise to keep you engaged and also increase your skills and hopefully, you managed to get everything
working in the end, maybe with some help of the solution, which is totally fine.
Don't be too hard on yourself,
everybody needs that
in the beginning.
I hope you had fun with me in this lesson.
In the next lesson, we've got our final project of the module where we're going to be building an app
similar to the Whisper app using the Secrets API.
For all of that and more, I'll see you there.