Transcripts
1. Class Introduction: Welcome back to Module four
of the Express JS course, BilRstful APIs with Express. This class is a continuation of the Express JS course series. My name is Shan Ragunci and I will be your guide
on this exciting journey. With years of
experience building scalable APIs and
real time systems, I'm here to help you
master the art of building restful APIs
with Express JS. In this module, we
will cover everything. You need to build modern
and efficient restful APIs. This includes designing
restful services and creating your first
Express S server. Using tools like
Normon to streamline development and postmen
to test your ABIs, securing your app with environment variables
and validating input to keep it safe handling SCTP methods
like get post, put, and delete to
interact with data, and mastering dynamic routing to make your API flexible
and powerful. This class is perfect for developers with a basic
understanding of node JS. Want to take the next step
into API development. If you've ever wanted to create your own
backend services, this module will show you
exactly how to do it. By the end of this module, you will have the
skills to design and build restful APIs
that are secure, scalable, and ready
for production. These are essential skills
for backend developers and a critical step toward
becoming a full stack expert. Finally, our hands on project will guide you in
building a fully functional, restful API from scratch. You will create routes
for handling get, post, put, and delete requests, secure your app with
environment variables, and validate input to
ensure reliability. I'm so excited to help you build powerful and scalable
APIs with Express JS. Let's dive in and get started. See you in the first lecture.
2. Overview of this Section: I So earlier in section two, where we talked about
node module system, you learned about
this STDP module. We use this to create a web
server that listens on port 3,000 and responds to
request to these endpoints. So the root or API courses. Now while this approach
is perfectly fine, it's not ideal for building a complex application because in a large complex application, we might have various endpoints, and we don't want to hardcore all these statements
in this function. So in this section, we are
going to look at Express, which is a fast and
lightweight framework for building web applications. So next, we are going to
look at restful services.
3. Designing RESTful Services with Express.js: Let's start this section by a brief introduction
to Rest PL services, also called RestPL APIs. If you already know
what rest is all about, feel free to skip this video. So earlier at the
beginning of the course, I introduced you to the
client server architecture. So most if not all, applications we use these days
follow this architecture. The app itself is the client or the front
end part under the hood. It needs to talk
to the server or the back end to get
or save the data. This communication happens
using the SDDV protocol, the same protocol
that powers our web. So on the server, we
expose a bunch of services that are accessible
via the STTBPtocol. The client can
then directly call these services by
sending STTPRquest. Now, this is where rest
comes into the picture. Rest is short for
representational state transfer. And I know it probably
doesn't make any sense to you because it was introduced by a PhD student as
part of his thesis. But the theory aside,
RST is basically a convention for building
these SDDB services. So we use simple
SGTPPtocol principles to provide support to create, read, update, and delete data. We refer to these operations altogether as crud operations. Now let's explore
this convention using a real PAL example. Let's say we have
a company called Fair Wheels for
renting out cars. We have a client app where we manage a list of our
customers on the server. We should expose the service
at an endpoint like this. So fairwheels.com slash
API slash CustomerS so the client can
send SGTBRquest with this endpoint to
talk to our service. Now a few things about this
endpoint you need to know. First of all, the address can
start with SGDP or HTTPS. That depends on the application
and its requirements. If you want the data to be
exchanged on a secure channel, you would use GDPs. After that, we have the
domain of the application. Next, we have API. This is not compulsory, but you see a lot
of companies follow this convention to expose
their restful services. They include the word API
somewhere in the address. It can be after the domain, or it can be a subdomain
like apfairwals.com. There is no hard and fast rule. After that, we have customers, which refers to
the collection of customers in our application. In the rest world, we refer
to this part as a resource. We can expose our resources
such as customers, cars, rentals on
various endpoints. So this is our endpoint to
work with the customers. All the operations
around customers, such as creating a customer
or updating a customer would be done by sending an STDB request
to this endpoint. The type of the GTB request determines the kind
of the operation. So every SGDP request has
what we call a verb or a method that determines
its type or intention. Here are the standard
HTTP methods. We have get for getting data, post for creating data, put for updating data, and delete for deleting data. Now let's explore each of these using our
customers example. To get the list
of all customers, we should send an STD get
request to this address. Note the plural name customers. Here it indicates a
list of customers. So when we send an STP get
request to this endpoint, our service should send
us something like this. So we have an array
of customer objects. If we want a single customer, we should include the ID of
that customer in the address. Then our server would respond with a customer
object like this. Now to update a customer, we should send an STDPput
request to this endpoint. And note that again, here we are specifying the ID of
the customer to be updated. But also we should include the customer object in
the body of the request. So this is a complete
representation of the customer object with
updated properties. We send this to the server, and the server updates
the customer with a given ID according
to these values. Similarly to delete a customer, we should send an STDP delete
request to this endpoint. But here we don't need to include the customer
object in the body of the request because all we need to delete a
customer is an ID. And finally, to
create a customer, we need to send an
STDPPostRquest to this endpoint. Not that here because we
are adding a new customer. We are not dealing with
a specific customer. We don't have the
ID in the address. We are working with a
collection of customers. So we are posting a new
customer to this collection, and that's why we should include the customer object in
the body of the request. The server gets this object and creates a customer for us. So this is the
restful convention. We expose our resources such
as customers using a simple, meaningful address and support various operations around them, such as creating
or updating them using standard GTP methods. Throughout this section, you're
going to learn how to use the express framework to build the restful service for
managing the list of customers. However, in this section, we won't be doing
any database work because that will bring
in additional complexity. Our focus will be purely
on building SDDP services, and we will use a simple array in memory to keep the
list of our customers. Later in the course, we will
look at using a database.
4. Express.js: An Introduction: So here is the quote that we wrote in the section
about node core, where I introduce you
to the STDP module. So we can see with STDP module, we can create a web server. Here we have a callback
function that takes two parameters,
request and response. And with this request object, we can check the URL of
the incoming request. So with this, we can define various routes for
our application. So if you have a
request for, let's say, API purses, this is how we are going to
respond to the client. Now while this approach
certainly works, it's not very maintainable
because as we define more routes
for our application, we need to add more I blocks
in this callback function. So that's when a framework
comes into the picture. A framework gives our
application a proper structure, so we can easily add more routes while keeping our application
code maintainable. Now there are various
frameworks out there for building web applications and
web servers on top of node. The most popular one is Express. So if you head over tonpmjs.com, let's search for Express. So the current version
is version 4.18 0.2. Let's have a quick look here. So here on the right side, look at the statistics. There have been over 27
million weekly downloads. It's a very popular framework. It's also very fast, lightweight, and
perfectly documented. So now, back in the terminal, let's create a new
folder for this section. So I'm going to call
this Express Themo. Now let's go inside this folder, run NPM in it with yes black. So now we have a package
JCNFle and finally, we can install Express. Beautiful. In the next lecture, I'm going to show
you how to build your first web server
using Express.
5. Constructing Your First Express.js Server: All right. Now in VS code, let's add a new file app dot js. So in this file, first, we want to load the
express module. So we use our required function, give it the name of our
module, which is express. Now this returns a function. We call that express. Okay. Now we need to call
this function like this. And as you can see, this returns an object
of type express. By convention, we
call this object app. So we store the result
in a constant call app. So this represents
our application. Now, this app object has a
bunch of useful methods. We have methods like t, post, put, and delete. All these methods
correspond to STDP verbs or STTP methods that I told you about
earlier in the section. So if you want to handle an DDP post request
to an endpoint, you would use app dot post. Now in this lecture,
we just want to use app dot G. We want to implement a couple of endpoints that respond
to an TDP Get request. So this method takes
two arguments. The first argument is
the path or the URL. So here, I'm going to use slash to represent the
root of the website. Now the second argument
is a callback function. This is a function that
will be called when we have an STDPGRquest to this endpoint. Okay, so this callback
function should have two arguments request
and response. So this goes to a code block. Now this request
object has a bunch of useful properties that gives us information about
the incoming request. If we want to learn about
all these properties, it's best to look at the express documentation because
in this course, we are going to use only a
handful of these properties. So head over to
expresj.com on the top, look at API reference
version four. Now here, you can see
the request object, and below that, you can see all the properties that
are available to you. We have base URL, we have body to read the
body of the request, Cookies, fresh host name, IP method, original URL, parameters, and so on. So back to our code, when we get an GDP get request to the root
of our website, we are going to respond
with a Hello world message. Respons dot CNN Hello WW. Now this is how we
define a route. We specify the path or the
URL and a callback function, which is also called
a route handler. Now finally, we need to
listen on a given port. So we call app dot LICEN We
give it a port number 3,000. And optionally we
can pass a function. That will be called
when the application starts listening
on the given pot. So once again, we use the arrow function syntax to display something
on the console. So console dot log
listening on port 3,000. Now, back in the terminal
node app dot js. Okay, we are listening
on port 3,000. Now, let's switch
over to Cron and go to Local host port 3,000. So here's our Hello
world message. Now let's define another route. So once again, we are
going to call app dot cat. Now, this one is going to
be slash API slash CoorsS. Once again, we pass
the function with two arguments that is
request and response, and this goes to a cod block. Now in real world scenario, here we want to get the list of courses from the database
and return them. But as I told you before, in this section, our focus is purely on building
these endpoints. We are not going to
do any database work, so I'm going to simply
return an array of numbers. So response that sent pass
an array of free numbers. In the future, we can replace these numbers with
actual course objects. Now, back in the terminal, we have to stop this
process and start it again. So press Control and C. Okay, one more time,
note, app to chase. Now back in Pro, let's head
over to slash APIs OSS. Look, we have an array
of free numbers. Beautiful. So this is what I want you to
pay attention here. In this implementation, we
don't have those I blocks. We define new routes by
calling app dot get. With this structure, as
our application grows, we can move some of these
routes to different files. For example, we can move
all the routes related to courses to a separate
file like courses dot JS. Express gives our application
a skeleton, a structure.
6. Efficient Development with Nodemon: So far, you have noticed that every time we make
a change to this code, we have to go back in
the terminal and stop this process and start it again. This is very tedious. So I'm going to show
you a better way. We're going to install a node
package called Nord mode, which is short for node monitor. So in the terminal, NPM install G because we want
to install this globally, so we can run it anywhere. And the name of the
package is Nord Mode. As I told you before,
if you're on Mac and you haven't configured
the permissions properly, you need to put
pseudo at the front. All right? Non
mode is installed. So with this, instead of running our application using
node, we use node mode. Okay? Now you can see Normon is watching all
the files in this folder, any files with any extensions. So if you come
back here and make a simple change and
then save the file. Now, look, in the terminal, Normon restarted our application or our process due
to the changes. So we don't have to do
this manually anymore. Now, back in the browser, if we send a request to
the root of the website, we can see our new
message displayed here.
7. Securing Configurations with Environment Variables: Now one thing we
need to improve in this code is this hard
coded value for the port. So we have used 3,000
as an arbitrary number. While this may work on
the development machine, it's unlikely that this is going to work in a
production environment. Because when you deploy
this application to a hosting environment, the port is dynamically assigned by the
hosting environment. So we can't rely on
3,000 to be available. So the way to fix this is by using an
environment variable. Typically in hosting environments
for node applications, we have this environment
variable called port. An environment
variable is basically a variable that is part of the environment in
which a process runs. Its value is set outside
this application. I'm going to show you how
that works in a second. So in this application,
we need to read the value of this sport
environment variable. And the way we do that is by
using the process object. We have this global
object called process. This object has a
property called N, which is short for
environment variables. And after that, we add the name of our
environment variable. In this case, for so if this is set, we are
going to use this. Otherwise, we are
going to use 3,000. Now we can store the result
in a constant called port. Okay, let's delete this. And finally, we need
to replace 3,000 with port and also change our
message accordingly. So I'm going to replace this
single code with backtick. So we can use a
template literal. And here we are going to replace 3,000 with a dynamic value. So we add Dosine, curry braces, and then
add our constant. Now, back in the terminal, let's run this application
using Node mode. So on this machine, you can see, I don't have an environment
variable called port. That's why 3,000 is used as
the port for the web server. Now I'm going to set an
environment variable. So let's stop this process. On Mac, we can set an environment variable by
executing the export command. If we are on Windows, you should use set in
command prompt and dollar and colon in Power Shell. Now, we add the name
of the environment variable in this case, port and set its value. I'm going to use 5,000. So now we have this
environment variable called port with a value of 5,000. With this, we run
this application, Norman you can see that now we are
listening on port 5,000. So this is the proper way to assign a port to your
node applications. You should attempt to read the value of an environment
variable called port. If there is a value,
you should use that. Otherwise, use an
arbitrary number for your development machine.
8. Dynamic Routing with Route Parameters: All right, currently, we have a route for getting
the list of courses. Now in this lecture,
I'm going to show you how to create a route
to get a single course. So earlier in this section, where I talked about
restful services, you learn that in order
to get a single course, we should include the ID
of the course in the URL. So endpoint should be like
this slash API CSS one. Assuming that one is
the ID of the course. So let's see how we can
implement a route like this. So app dot get, we add the path that is slash
API slash Courses. Now here we need to
define a parameter. So we add column and ID. This ID is the name
of our parameter. Here we could use anything. It doesn't have to be ID. It could be course ID, but ID is shorter and
more conventional. Now we add our route
handler function. So request and response goes to. Now in order to read
this parameter, we use request dot forms dot ID. So for now, let's just
send this to the client. So response dot N. Okay.
Back in the browser. Now let's head over
to slash API COSSSO. So you can see we successfully read the value of
this parameter. Also, it is possible to have multiple parameters in a route. For example, imagine you are building a service
for powering a block, so we could have a route
like this post your month. So we have two parameters. And with this, we can get all the post for the given
month and the given year. Now we can read these
parameters just like before. So request dot PRMs
dot year or month. For this demo, let me show you this request dot PREMSObject.
Back in the browser. Now let's head over to
API post 2023 and one. So this is our
request PAMs object. We have two
properties and month, and they are named based
on our route parameters. With the Express, we can also get query string parameters. These are parameters that we add in the URL after
a question mark. For example, we can
get all the posts in January 2023 and sort
them by their name. So we add a question mark, sort by set this to name. This is a query
string parameter. We use query string
parameters to provide additional data to our
back end services. So we use route parameters for essential or
required values, whereas we use query
string parameters for anything that is optimal. Now, let me show you how to
read query string parameters. So back in VS code, instead of request Dot PRMs, we use request dot query, save back in Chrome, and
this is what we get. So query parameters
are stored in an object with a bunch
of key value pairs.
9. Mastering HTTP GET Requests: I All right. Now let's implement
a new endpoint to get a single course
from the server. So first of all, let's
change this back to courses and add the
ID parameter here. Okay, now on the top, let's define an array
called courses. So constant courses. We set this to an array. And in this array, we're going to have three
course objects. So each object should
have a couple of properties, ID and name. And of course, we can have more. But for simplicity, I'm just going to stick to
two properties here. Okay, now let's duplicate
this line and change the IDs as well as the
name two and three. So we have two endpoints, one to get all the courses and the other to get a
single course, right? In the first one,
we are going to return our courses array. Okay? Now, in the second one, we should write some
logic to look for the course with a given
ID. So let me delete this. First we are going
to courses dot FIE. This is a method
that is available on every array in JavaScript. As an argument to this method, we need to pass a function. This function will
be used to find a course that matches
a given criteria. So we use the arrow
function syntax. T goes to, and here we write some logic that
returns a Boolean value. This boolean value determines if this course is the one
we are looking for. So C ID should equals
request dot proms dot ID. However, this request that
Pam ID returns a string. So in order for this
comparison to work properly, we need to pass this
string into an integer. So we call pasen, which is one of the
global functions available in Javascript, and then get the
result and store it in a constant called quote. Now we can either
use let or constant. We use let if you want to define a variable that we can reset later and we use constant if we want
to define a constant. In this case, I don't want to reset the course later
in this function, but again, that's perfectly
fine to use let here as well. It's just personal preference. We get the course object. Now, if this course doesn't
have a value, in other words, if we don't find a course with
a given ID, by convention, we should return a response with the TDP status code
of four or four. That means object not found. So this is one of the
conventions of restful ABIs. If the client asks
for a resource, but that resource does
not exist on the server, we should return a response with a status code
of four or four. So return response dot
status four or four, and optimally, we can send a message to
the client as well. So send the course with a
given ID was not found. Okay? Now, otherwise, if we do have a course
ID with that ID, we are simply going to
return that to the client. So response dot SN course. Now let's test this. B in the browser,
let's head over to slash API slash
courses slash one. So we have a course with ID one, and that's why we get this
SN object in the response. Okay, if I change it to
ten, we get this message. The course with a given
ID was not found. And to ensure that
the status code of this response is four or four, we can open up from
developer tools. So right click Clear,
go to inspect. And then on the network tab, make sure you don't
have a filter here, select all and then refresh
the page by pressing Control R on Windows
or Command R on Mac. So here's a request that
we send to the server. You can see that status
code is four or four, which means not found.
10. Handling POST Requests Effectively: So far, we have
created two routes that respond to STTPGRquest. And we use these routes to get all the courses as well
as a single course. In this lecture, I'm
going to teach you how to respond to STTPPostRquest. So we use an TTP post request
to create a new course, so app dot post. Instead of the G method, we use the post method. Now, similar to the G method, we need to specify a pap. So that should be slash EBS CSS because we are going to post with a
collection of courses. That's why I use a
plural name here. Then we need our route handler, so request and response
goes to Card black. In this route handler,
we need to read the course object that should be in the
body of the request. Use its properties to create
a new course object and then add that course object
to our courses array. Let's create a new
course object. Constant course. Again, I'm using a
conste because we are not going to reset
this course object later. So let's set this
to a new object. Now here, because we are not
working with a database, we need to manually
assign an ID. So ID, and we get the number of elements
in our courses array, so courses dot length, and simply add one to it. In the future, when we
work with a database, the ID will be assigned
by the database. Next is the name property. Now we need to read this from
the body of the request. So request dot body dot Name. So here I'm assuming that
in the request dot body, we have an object and that
object has a name property. Now, in order for
this line to work, we need to enable
parsing of JSN objects in the body of the request
because by default, this feature is not
enabled in Express. So on the top, after
we get the app object, we need to call app.us and
here we call express dot JSON. Now, this may look a
little bit strange or unfamiliar to you,
but don't worry. Later in this section, we are going to explore this in detail. Basically, what
we are doing here is adding a piece of middleware. So when we call
Express Jin method, this method returns a
piece of middleware. And then we call app to use that middleware in the
request processing pipeline. Again, we are going
to explore that in detail later in the section. So back to our new route andler, we have a course object. Next, we push it in our array, so courses push course. And finally, by convention, when we post an
object to the server, when the server creates a new
object or a new resource, you should return that object in the body of the response. So response dot SN course. The reason for this is because we are assigning this
D on the server, we need to return this course object to the client
because chances are the client needs
to know the ID for this new object or
this new resource. So this is how we handle
HTTP post request. In the next lecture,
I'm going to show you how to
test this endpoint.
11. Testing Endpoints with Postman: All right, to call
SDDP services, we are going to use
the Postman API. So if you haven't
used Postman before, postman.com and download
the app in your system. So on the top right, go to
product get started download. Once downloaded, open this file and install it in your
system like this. Once done, you can open Postman as any other
app in your system. Now here, it may ask you
to sign up for an account, but you don't have to do this. As we are working locally, we can use a
Scratchpad, all right. Now on this page, we can
create a new TTB request. So from this drop down menu, we set the type to
a post request. You put the URL here. In this case, that's
TDP, local host. On my machine, I'm using
port 3,000 to host this application, APIs Courses. Now we need to set the body of this request from this list, select Pro and then JSN. So with this, we can put a JSN object in the
body of the request. So let's add an object here
and give it a name rape. Per name, we set this to new
course and then finally set. You can see the status
of this request is 200, which means the request
was handled successfully. And here's the body
of the response. So ID is four because now we have four
courses in our array, and this is the same name
that we send to the server. So this is how we test HTTP
services using Postman. Now in this implementation, we have assumed that
there is an object with a name property in
the body of the request. What if the client
forgets to send this property or sends
an invalid name, perhaps a name
that is too short. That's where input validation
comes into picture, and that's the topic
for the next lecture.
12. Safeguarding Your App with Input Validation: In this lecture,
I'm going to show you how to do input validation. So as a security best practice, you should never ever trust
what the client sends you. You should always
validate the input. So in this particular example, because we're dealing
with a simple object with only one property
that is name, we can write some
validation logic like this. So I request dot body
dot name doesn't exist or request dot body dot name length
is less than three, then we are going to return
an error to the client. The restful convention is
to return a response with the status code of 400. That means PAD request. So to do this, we call
response dot status 400, and then we can send
an error message. In this case, we can write a generic error message like name is required and should
be minimum three characters. Now in your implementation, you may want to
differentiate the errors. For example, if the client
didn't send the name property, perhaps you would just respond
with name is required. Or if they did send the name, but the name was
not long enough, you could send a
different error message. Then finally, we return here because we don't want the rest of the function to be executed. This is a basic idea. However, in real
world application, it is more likely that you will be working with a
complex object, something more complex than
this course object here. You don't want to write a
complex validation logic like this at the beginning
of your route handler. So let me introduce to a
node package that makes it really easy for you
to validate the input. So on Google, if you
search for NPM Joy with I, look, here's the first link. So here you can see there are over 8 million downloads weekly. It's a very popular package. Now let me show
you how to replace this validation logic with Joy. So first, back in the
terminal, let's install Joy. At the time of
recording this video, the latest version
is version 17.9 0.2. If you want to make
sure that we have the exact same experience as what I'm going to
show you in this video, then install this exact version. So NPM install hoy
at 17.9 0.2, okay? Now back in the code on the top, we need to load this module. So require Joy, get the result
and store it in a constant called Joy with J because what is written from
this module is a class. And as I told you
before, in JavaScript, we use pascal naming convention
to name our classes. So the first letter of every
word should be uppercase. Also, as a best practice, put all your required
pause on top of this file. This way, you can
easily see what are the dependencies
of this module. So this module app module is
dependent upon two modules. One is Joy, the
other is Express. We have this Joy class now
back in our route handler. Now with Joy, first, we need to define a schema. A Schema defines the
shape of our objects. What properties do we
have in that object? What is the type
of each property? Do we have an email?
Do we have a string? What are the minimum or
maximum number of characters? Do we have a number? What range
should that number be in? So this is a job of Schema. So here, first I'm going
to define a schema. On sent schema, we
set it to an object. This is the shape of
our course object. So here we want to
have a name property, and we set this to
Joy dot string. So we are telling Joy
that this is a string, and it should have a
minimum three characters, and it should be required. So it has a very fluent API. Again, you can look at the documentation to see all the methods that
are available to you. So here's our schema. Now we call schema dot Validate, and we give it request at body. Now this validate method
returns an object. Let's store that in a
constant called result. For this demo, I'm going to log this result on the console. So before we go any further, let's say this, go
back to the postman. Let's create another course. Now, back in the terminal. So this is our result object. It has two properties,
error and value. Only one of these
can have a value. So in this case, because we
send a valid course object, we have that object here as a value of the value property. If you send an invalid object, value will be null and error will be set.
Let me show you. So peg in postmen, let's remove the name property. Send now back in the terminal. Okay, look, here's
the result object. This is the error property. It's set to an object that
has validation error. Name is required. So
back to a route handler, instead of this manual
validation logic, we can check the value of
result thot error property. So if result that error, then we are going to send a
response with status code of 400 and in the
body of the response. For now, we can simply add
result dot error, okay? And you don't need this
console dot log anymore. Say. Now, back in Postman, one more time, I'm going
to send this empty object. Now, look at the response. So this is what we get. An object with these properties. Original details, which is
an array of error messages. So here's the first message. Name is required. Now this object is too
complex to send the kind. Perhaps you want
to simplify this. So back in the code,
one simple solution is to go to the details array, get the first element, and then access the
message property. So instead of using
the first element, you may want to access all
elements in this array, get their message property
and concatenate them. That's entirely up to you. So save one more time, let's send an invalid request, and now we get name is required. If you go to our request
and add the name property, but sent it to a string
that is only one character, now we get a different error. Name length must be at least
three characters long. So you can see Joy makes
it really easy to validate the input and return proper error messages
for the client.
13. The Art of the HTTP PUT Request: All right. Now let's see
how we can update a course. Let's add a new
route handler app. We use the put method
for updating resources. Now the part should be
slash API slash Courses. And here we need
a route parameter because we are dealing
with a specific course. So ID, now route
handler function, request and response
goes to a quod black. All right. Now, here's the
logic we need to implement. First, we need to look up
this course with a given ID. So look up the course. If the course doesn't exist, if not existing, we need
to return four or four. That means resource not found. Otherwise, we need to
validate the course, make sure it's in good shape. If valid, we need to
return a 400 error, which means Pat request. If you get here, that
means everything is good. So we update the course and return the updated
course to the client. This is a logic we
need to implement. We already have some code
that we can reuse here. I'm not going to type
everything by hand. I'm going to copy some code from our other route handlers. First, we want to
look up the course and if it doesn't exist, we want to return a
four or four error. For that, I'm going to go to this other route handler
where we get a single course. This is a logic we
are interested in. We look up the course
and if it doesn't exist, we return a four or four error. So copy these two lines we
are done with the first part. The second part is
all about validation. For that, I'm going to
go to our post endpoint. So here we need to
copy the schema, as well as this line for validating the
request body using joy and the code to return
400 if it's invalid. But there is a problem
with this approach. The problem is, in this case, we have a very simple schema. What if you are dealing with a complex object with
quite a few properties? Then our validation
logic would be duplicated into different
route en loads. So let's just copy the
boat for now and then we'll come back and refactor
it to make it better. So copy these lines
and paste it here. So we are validating, and if you have an
error in the result, we are going to return
this 400 error. So this is our second part. We have the schema, we validate, and if we have an error, we return the 400 error. We are done with the second
part. Now the third part. So at this point, we
have a course object. We can update its properties, so course dot nem, we set that to
request dot p dot. And of course, if we
have other properties, we'll set them here as well. So we are done with
updating the course, and finally, we need to return the updated
course to the client. Response dot CN course. This is how we handle
an STDBPutRquest. Now, I told you that we have duplicated this
validation logic. I'm going to extract these few lines into a
separate function that we can reuse both in this route handler for handling an STTPPutRquest, as well as the other
one we wrote in the last lecture for
creating a course. Now let's define a
function here and call it validate course. We give it a course object. Now in this function, we
should have the schema as well as this line for
validating the course. So cut these few
lines, paste it here. Now, instead of validating
request dot body, we are going to validate the argument that is
passed to this method, so that would be
the course object. Finally, we can simply return
this result to the call. There is no need to
define a constant. So with this new implementation, we have all the
validation logic in one place. Now we
can reuse this. So here's our put method. We define a constant call result and set it to validate course. And as an argument, we
pass request dot body. Now we can make this code a little bit cleaner and shorter by using object destructuring feature in modern Javascript. So look, here we get this
result object and we are accessing result
dot error property in two different places. Since all we're interested
in is this error property, we can get this using
object restructuring. So let me duplicate
this line and show you how object
destructuring works. With object restructuring, when declaring a
variable or a constant, we add culebrass and then here we add the property
of the target object. So in this case, the target
object that is returned from our valid course method has two properties, error and value. In this case, we just
want the error property. So we put that
between Cul braces. So this is equivalent to
getting result dot error. We use this notation. Okay. Now with this, we don't have to
repeat result error into different places. We can simply use error, okay? So this is object destructuring. Now we don't need this
first line anymore. And finally, before we
finish this lecture, we need to make one more
change in this code. So we need to use this new
way of validating a course in the route handler for handling
our STTP post request. So copy, this is our handler
for creating a new course. So we don't need to
use the schema here. We move all that logic to
our validate course funtion. I'm going to delete
this and piece the code that we copied
from the other method. So we call validate course, use object restructuring syntax, and if you have an
error, we return the 400 response to the client. Now finally, let's test our new endpoint for
updating a course. Now, back in Postman, we need to change the type
of this STDP request to put, change the URL, and add a
valid course ID like one. Here we have a
valid course object with name set to new course, so sent we get a 200 response which is successful and here's
the updated course. So if you open a new tab
and send an TPG request to localized APIs courses, you should see that
list of our courses. First course, its
name is updated. Perfect. Now, let's test
the other scenarios. What if we send an invalid ID? We ten. Send the course with
a given ID was not found, and you can see the response is four or four, which
means not found. Finally, what if we
send a valid course ID but an invalid course object? So I'm going to remove
the name property, S that we can see we have a
bad request or 400 error. And here's the error message. Name is required. Next, I'm going to show you how to
handle SDDP delete request.
14. Executing DELETE Requests Correctly: And out of all the CRD
operations we have implemented, create, read and update. So in this lecture, I'm
going to show you how to respond to HTDP
delete request. It's very simple and similar
to what we have done so far. So here's our app object. We call that delete method. Give it a path that
is slash API Courses. And of course, we
need a parameter because we are working
with a specific course. Then our route handler request and response goes
to the Cord block. Now here, first, we need
to look up the course, a course with a given ID. If it doesn't exist, then we
need to return four or four. Otherwise, we are
going to delete it. And by convention,
return the same course, the course that was deleted. So again, I'm going to borrow some code from other
route handlers to look up the course and
return a four oh four error. Let me go back to
our route handler for the STP put request. So these first two
lines is for looking up the course and returning
a four oh four error. So copy these two lines back here. That is our first part. Now to delete a course, first, we need to find the index of this course in our
courses array. So courses dot index of
course, we get the index, store it in a constant, and then we can use
the splice method, remove an object from
our courses array. So courses dot Splice, we go to this index
and remove one object. So this is a delete part. And finally, we need to return
the response to the claim. So response that send
this course object. Now, let's test this. Bag in Postman, let's
change put to delete. First, I want to send an
invalid course ID like ten s so we get a
four or four error, not found with this message. Perfect. Now let's
delete the first purse. Course with ID one. Then we get the same course
object in the response. And if we go to our second tab where we have the
list of our courses, let's send this one more time. Okay, now, look, we don't
have our first purse anymore. We only have courses
with ID two and three. All right. Before
we go any further, look at the handler for
responding to put request. If there is an error,
a shorter way to write the same code is
to put the return here, and then we don't
need a code block. We can put everything
in one line. Now finally, let's
have a look at the handler for
GDP post request. Here it is. Again, I'm going to use the same technique
to clean up this code. So if we have an error, we simply return and get rid of the extra noise in this
code. That's much better.
15. Project: FareWheels App: All right. Now it's
time for an exercise. So from this lecture, we
are going to start building the backend services for our
fair wheels application. As I told you
before, fair wheels is an imaginary service
for renting out cars. So throughout this course, we are going to
build the back end of fair wheels bit by bit. Our first task is to
create a service for managing the list of car
companies or manufacturers. So each car has a manufacturer
like General Motors, Tesla, Ord, and so on. We should have an endpoint
for getting the list of all the companies because somewhere in our
client application, perhaps we have a drop down list for the user to
select a company. So we need an endpoint to
get all the companies. We should also be able to add a new company as well as update or delete
an existing one. So before going any further, I want you to put what you have learned so far in practice, and this is going to be
your assignment as well. So even if you're an
experienced developer, don't say no or even
make an excuse. I know how to do this.
This is so easy. I know it's easy,
but what matters now is that I want you to
get used to this syntax. So go ahead, start a new
project from scratch, all it bear wheels and build this TDP service for managing
the list of companies.