Loading video player...
Hey, what's going on everybody? It's
Caleb and welcome to your video on API
concepts, design, and architecture. I'm
really excited for this because this is
the start of a series of videos on
application development, backend
development, API development. We're
going to talk about a lot of concepts,
but we're also going to follow up with
hands-on exercises, and building out
applications. So, first thing I wanted
to mention is you'll want to check for
the playlist link so you can watch
through all of these videos. Now, this
is a pretty long one. It's going to set
the foundation. So, there's a couple of
things I want to get out of the way at
the beginning. So, I already mentioned
the playlist, but I also want to mention
the notes. I have extensive notes for
this lesson and some of the upcoming
lessons as well. So, you will want to
check that out. I'll have a link down
below. So, those notes act as a
companion for these lessons. It'll have
everything we're talking about,
different code examples, references, and
additional information that'll go along
really well with these lessons.
The other major thing is that some of
these lessons will be concepts, some of
them will be hands-on. You definitely
want to follow up the concepts with
hands-on material so you can solidify
what we're talking about here. It's very
critical that you follow along and
actually build APIs so you know how to
take what we're talking about here and
apply it to the real world. And then the
last thing, this isn't really an
advanced series, but we're not going to
start from the absolute beginning. So
we'll introduce APIs without much prior
knowledge, but if you need additional
computer science principles,
I have a fundamentals course which I'll
have a link down to below. This is not
mandatory, but if you find that the
material here is going a bit fast, I'd
recommend you go through that first. Oh,
and one last thing, timestamps.
We're going to cover a lot of
information, so you'll want to use the
timestamps available on the timeline or
in the description to jump to whatever
section you need. This will be handy if
you want to reference certain sections
later, or if you don't get through the
full lesson in one go, you can jump back
to where you left off. So, a while ago
here on YouTube, I did a REST APIs in
1hour video, and I think this was a
pretty good introduction, but this
video's focus is going to be a bit
different. First, we're going to go in
more depth. We'll cover the same
material with a lot of additional
information and cover more material in
this lesson because this is going to be
dedicated to just all of the API
concepts you need to know to be a
software engineer. We'll talk about the
different types of APIs. You might be
coming here looking for REST API
information, which is the majority of
what we're going to talk about, but
there are other API types as well. So
we'll talk about how REST APIs are
different than these other types.
Additionally, we're going to bring in
more system design concepts.
So this gets into a little bit more of
dealing with different servers and how
to architect your API in a way that it
can be scalable. So we want to build
scalable systems
that can support many many users. So, if
you're just getting started, some of
these things you might not worry about
because you're just trying to build your
first API. We're going to do that, but
then we're going to go deeper and talk
about more stuff you should know. We'll
also talk about pageionation,
authentication, versioning, and various
other intermediate and advanced topics
when it comes to building out
applications. So, I'm very excited for
this video. Consider this to be the
foundation
that you're going to build the rest of
your knowledge on when it comes to
application development and APIs. So, I
want to introduce you to everything you
need to be successful. So, we're going
to cover a lot of different things in
this lesson. By the end of this video,
you're not going to be an expert on
everything, but you'll have a much
better idea of everything you should
know, and we'll continue to discuss all
of those different topics in future
lessons. So, let's first start talking
about what an API is, what it stands
for.
So, this stands for application
programming interface.
And this allows us to build applications
that talk to each other.
So when you hear the term interface, you
should think of the surface area of
potential interactions for an app. So
let's say we build this app here.
This app might work with a database and
do all these complex things.
But we don't just give everybody access
to the database. We give specific things
that the user can do. For example, we
could get some data or we could delete
some data. And these different things we
can do that concept is called an
interface. And it allows us to interface
with other applications. So we might
have a different app over here.
And we can interact with app one from
app 2 because app one has an API.
So these two apps could be two
completely different apps. For example,
I might be building some calendar app
and I'm using Google Maps API.
Basically asking, hey, how long would it
take to get to my appointment? And the
API gives me back a response.
So basically, I just enhanced the
functionality of my app by using some
other apps API. This is a very common
structure. Another very common structure
is instead of using a completely
separate API, I might actually split my
app out into backend front end. So
logically the same product or same
purpose but two separate code bases. And
this front end will just make API
requests to my backend. This backend can
then grab data from the database or make
sure that whoever is asking for this
information is authorized to ask for
that information. So we're not just
giving data out to anybody. And then
once the back end does all the
processing and whatnot, it sends the
data back to the front end. The front
end can then display it all pretty and
cute on a web page. So this is the other
major structure that you will see APIs
for in this situation. You can still
think of these as two apps. We have a
front-end app and a backend app. They're
just working together to provide a
single product.
So this is different than if I use some
third party API to enhance my app's
capabilities. But both of these are
possible. Doesn't really matter. The
whole idea with an application
programming interface is you can do
whatever you want. Basically, we create
an app and we expose different
capabilities to the outside world to
interact with our app. So that is the
general idea around APIs. So this is
what we're building, right? But there
are actually different types.
So these types of APIs, that's what I
want to talk about now. The main one
we're going to start working with is a
REST API. So, R S where you might see
RESTful
which is an API that follows REST
principles. So, that's probably the
first thing you should become familiar
with, but we're going to compare it to
some of the other options out there. So,
let's talk about the types of APIs. And
I'm going to talk about some of the most
common ones, but there are other ones
I'm sure. So, the first one we just
mentioned
would be a REST API. REST stands for
representational state transfer. So it's
some way to transfer state between apps.
REST will use HTTP. So we'll be able to
do this inside of a browser and it works
with JSON. JSON is an object notation.
So this describes how we structure the
data that we send over the line. Now
another one you might hear is SOAP.
Now I never use SOAP. My temptation to
make some stupid joke about real world
soap is unbearable. This is an
alternative to rest.
This was used a lot more in earlier
applications. So you might see this for
legacy systems
or enterprise systems.
A big difference with these SOAP APIs is
that they use XML, which is you can
imagine JSON, but 10 times more annoying
and difficult to work with. Then you
have XML. So if you're building a new
system, I wouldn't use SOAP, but you
should definitely be familiar with it,
at least an idea. So if you do come
across a SOAP API, you're not like, "Oh,
what's this?" That'll be important if
you're building a new system that
integrates with an old system. that old
system might not have a REST API and you
might need to use SOAP. Even though
you're building a new system, the
interaction with the old system, you
need to adhere to the API of the old
system. So say this is the old system,
you might be making new upgrades and
instead of completely replacing
the old, you might just make a new app
that integrates with the old app
providing new features or new interfaces
for users.
But for this you might need to use
whatever the old app uses for
interaction. So that might be a SOAP
API. Next up we have GraphQL.
Now, if you're familiar with databases,
you might be familiar with SQL. And this
is structured query language. GraphQL
works in a very similar way, but it's
not to interact with a database
directly. Rather, it's to interact with
a backend.
So, in this situation, instead of
exposing multiple endpoints,
this would be the traditional rest
approach.
What we'll do instead is we'll just
create a backend that is a very pretty
back end that has one GraphQL endpoint
that the front end can connect to
or the other app can connect to and then
the front end here does the decisions on
what it wants.
So you can think of it as the front end
providing a query to the back end and
then the back end provides the
appropriate response. So this is a
really common thing. Usually I would
recommend people learn this. So if you
already are familiar with REST, you
should probably get some experience with
GraphQL. However, if you're brand new, I
would recommend first learning REST.
Next up we have GRPC.
Now you may have heard of RPC before,
which is remote procedure call.
You can think of this as a way to
execute things
on the back end. But when we prefix it
with G, this is a specific protocol, the
Google RPC protocol. Now, many people
are going to say that this G stands for
Google.
However, I think officially this stands
for
GRPC, remote procedure call.
So, it's just a recursive acronym.
You'll see this quite commonly in
different technologies.
But ultimately, when you see gRPC, you
can think Google remote procedure call.
And this is a specific type of API that
uses something called protocol buffers
or protobuffs.
So instead of XML or JSON, we'll have
protocol buffers.
So this is an approach to serializing
data that's very effective. It it
reduces the uh size of the data as much
as possible, allowing for very fast
transfers between apps. This is really
common for micro service architectures.
So let's say instead of just having a
front end and a backend, you might have
all these different components that
interact with each other
and all of these work together to
provide
the architecture for some app.
This generally is called a micros
service architecture and using
protobuffs is pretty common for this for
that cross app communication although
not required. You could just use a rest
api. So with this you will have files
that are of the prototype
not prototype prototype and these
define a structure for the types.
So every single app can use these proto
files to establish the structure of the
data in their individual apps whatever
language that might be. So this is
really great working across multiple
different languages. We can define all
of the types with these protoiles and
there's ways to transfer from a protoile
into a certain type for whatever
language you're working in. Now I would
say those are the main four you should
be familiar with. You can also use
things like websockets to interact
between apps. So you can build a
websocket API
and a websocket is a birectional
channel to communicate.
So if we have a backend and a front end
or two apps, they don't have to be
backend front end. We typically with a
REST API, we'll make a request to the
back end and then the back end gives a
response. But with websockets, the
backend can also send data directly to
the front end without a request.
Basically, the way this works is the
front end opens a connection
and then that connection is maintained
and the communication can then happen
from either direction as long as that
connection is maintained. This is really
common for real time applications.
So if something happens on the back end
and we need to immediately tell the
front end, then you could say this is a
real time app. For example, a
communications app such as chat or
notifications
and so forth. Anything where the
communication is initialized from the
back end. But do keep in mind that the
front end can also send data to the back
end as well. So here are some of the
other types of APIs. You can look up
others if you want to know more
information. These are some of the
things I'm hoping to cover here in this
playlist or on YouTube.
So, if you're interested in building
some of these things, you'll definitely
want to hit that subscribe button,
follow along for the journey. And now
what I want to do for the rest of this
video is zoom in on this one here.
REST APIs or as I mentioned you might
see restful APIs.
Once you have this down, you should be
pretty competent in cross app
communication and then picking up these
others is going to be a whole lot easier
because you understand the principles.
Now the actual way you do it is going to
be different. So there's some stuff
we're going to talk about that's
specific to restful APIs. So
specifically, we're going to have
different methods we're going to talk
about. We're going to have a variety of
end points.
We're going to have status codes,
response codes,
and we're going to be working with JSON
data. So if you're not familiar with
JSON, it's really, really simple. I'll
show you a very basic example right
here. right now, right at this moment.
Not going to delay. Just going to show
it to you. Okay, it's going to be right
here. So, JSON stands for JavaScript
object notation.
It looks very similar to an object in
JavaScript. If you haven't used
JavaScript though, it's no big deal.
Basically, you're going to open the
object with a curly brace. Then, you're
going to have a series of attributes.
These will be quoted such as name
and then a colon and then the value
and then a comma
and then another attribute quoted
and then a value such as 30. In this
case it's not quoted. This supports
different types here. So we can use a
string which we showed with Caleb. We
could use a number.
We can use a boolean true or false.
We can have nested objects.
That's an important thing here. We can
structure objects inside of other
objects.
And we can have arrays. I think we can
also have null as well, which you can
count if you want. So if you have an
attribute and you specifically want to
say there's no value for that attribute,
you can use null. Notice that there's no
quotes here. That would be a string
containing null. It's just null, the
keyword. Now, if you're coming from
JavaScript,
you might notice some similarities, but
within JavaScript code, you don't have
to quote the attributes. And you can
also use different types inside of an
object within JavaScript. So, for
example, you could use a date
or a function
or undefined.
These things are not supported in JSON.
So it's not a one one two JavaScript
objects. So I wouldn't even really
strongly associate this with JavaScript.
I would just think of it as JSON with
key value pairs surrounded by curly
braces. Okay, so we have a pretty decent
understanding of the structure of our
data. How do we use the structure to
build an API? What does a REST API look
like? Well, some of the things we just
mentioned, we'll have a method
for example and these are written in all
caps. Get this is an HTTP method. So,
REST API is built on top of the HTTP
protocol. So, with that, you'll have an
HTTP method. Get is a very common one.
This is used to retrieve data from a
server. And when you go and visit a web
page, you're actually making a get
request, even if you're not working with
APIs directly. And then you'll typically
have some resource.
So resource you can think of this as
here. Let me give you a bunch of other
abstract names. Entity,
an item or some database record.
This is basically the thing that we are
wanting to interact with. So an example
of this would be users.
And that would be something that might
give us back that same JSON structure we
saw earlier where we have the person's
name and their age. I'm going to go
through the example of comments posted
on a website. So this could be a social
media, it could be whatever you want,
anywhere that you can post a comment.
So let's say you have a video
and people can post comments below.
We need a way to be able to retrieve
this information from the backend and we
don't have direct access to the
database. So it's going to look like
this. We have the backend.
The backend stores that data in a
database.
We make a request for comments
and then that backend formats the data
as we need and gives it to us
in JSON.
Once we have this JSON data, we can work
with it on the front end to format it
and make it look nice to the user, which
is how we end up with
a web page with the post and then the
comments below it. So that's the general
workflow. Then when a user goes in here
and maybe posts a new comment, this is
going to follow that same pattern, but
now it's going to make a request to the
back end with a different method. So
instead of a get request, we're going to
do a post request. All right. At this
point, you have a pretty decent idea of
what a REST API looks like or how you
interact with it. You have a method, you
have some resource, and then you work
with JSON. That's how you communicate
back and forth. So how do you grow this
to then a collection of different
endpoints? So that's a word you should
know. You can think of the end point
as a combination of the method
plus the path.
The path here is basically a URL
describing what resource you're trying
to interact with or collection of that
resource. So let's take a look at an
example with comments. We're just going
to write out all of the URL structures.
And you can think of these as basically
the different interaction points or
interface
to your API.
So these will all probably be prefixed
with slash. So you start with a slash,
but you're going to have something
before that slash, which will be
whatever your base URL is, the backend
API URL. So it might be something like
mysight.comi
[Music]
and then it's pretty common to have some
version in here. So you might be on v2
or you might be on v1. basically a way
to create different API versions. Then
you will have the resource
and then if you're working with a
specific instance so not just all of the
comments but one comment in particular
then you can pass in an ID.
Now this is substituted in.
So when you visit the web page you're
not going to actually put ID. You'll put
in a value like five or 105 or whatever
the ID is for the element the resource
you're trying to work with.
So the way you describe that this is
substituted in. You might see something
like brackets ID or you might see colon
ID. The exact notation is irrelevant and
every framework is probably going to
have a slightly different structure. But
the idea is that we need to indicate
somehow that the user provides in an ID
to access that element. So for us, we're
just going to use curly braces ID.
However, there are some architectural
designs with the way you structure your
URLs and your code around the resource.
So, in this situation, let's say we are
working with comments.
Do you work with comments directly or do
you always work with comments through
something else such as the actual post?
So you might have post
the ID of that post
and then get the comments for that post.
This is a different structure where you
now think of comments as bucketed
underneath a different resource in this
case posts. And usually this is going to
be plural. So posts, id comments. So
we'll talk about some of these ideas of
nesting data as there are some
alternatives where you can use URL
parameters to query or filter data
differently. So we'll look at that soon.
But for now let's go with this approach
here where we are working with a parent
resource. We access a specific post with
an ID and then we can grab all of the
comments for that post. So let's write
out some example endpoints. We'll start
with the method and because we'll often
have the URL SL API potentially slv1 or
v2 I'm not going to put that every
single time. You can just think of that
as copied on all of these. So all we'll
have is slashposts
slash
id slash comments.
So this is the endpoint for retrieving
all of the comments on a specific post.
So we have some video. This video has
the ID of 1 2 3 and it has a series of
comments down here. The API endpoint to
retrieve this information
would be posts 1 2 3
comments.
So this is the URL you would use to
access all of the comments for the post
with the ID of 1 123. Now the next
method we're going to look at is post.
This is how you add data. Now don't be
confused because we're talking about a
resource posts.
This is referring to posts on some
social media platform like a video post.
Then we also have post which is an HTTP
method that means to create. That's
usually used to add new data. So when we
come up here and we say post, we're
talking about the method
and we're going to create a new comment.
So it'll be the same exact URL
structure. The only change here is the
method that we used. So the method is
used to tell the server what we're
trying to do. Because we're adding some
new data, we will need to attach the
comment
data itself in the body.
So when you make a request, you'll have
headers and you'll have the body.
So that's where the actual JSON goes.
So when we get some hands-on practice
with this, if you've never done this
before, I'll show you exactly what I
mean. So that's going to be important
anytime we're adding new data because
the URL itself doesn't give enough
information. It doesn't say what the
comment we're actually posting says. So
we need to include the actual comment
content and we do that in a separate
section called the body. All right. So,
you have a video post, you have comments
on here, and we know how to get them
all, but there might be a specific
comment. And when you create this
comment, that comment is going to have
its own ID. Let's just say it's 321.
Well, to access this comment, if it has
a unique ID,
we don't need the parent ID. We don't
need to know what the video ID is. So we
can access this without the nesting of
the post. So it'll look something like
this. Get slash comments
slash
id. So if we made that concrete it would
be slash comments
slash 3 2 1. And that'll give us the
comment content.
And most likely it would have the post
ID as well as part of that data. So we
could associate it with a certain post.
So if we needed, we could use that to
figure out what video it goes on. So
let's just add some notes here. So this
is to get all the post comments.
Add a comment to a post
and then grab a specific comment. Next
up, the next method we're going to learn
about is put. This is used to replace or
update some data. So if we're going to
edit our comment, we can use a put
request. Again, for all of these that
are working with a specific comment, we
don't need the parent post. So we can
just say comments
slash id. So notice these are the same
URL similar to get and post. The only
thing differentiating them is the method
used. So this will replace or update
comment.
Now there's another type of request we
can make which is a patch request
which works pretty similarly but there's
some key differences here that you need
to understand. So the URL will be the
same.
This is going to partially update.
So what that means is with patch if you
had some
document
and you had multiple things you wanted
to change in it with a patch you could
just select one of these things and
change it.
With a put request you will take the
entire information make some changes
and send the entire information back. So
you're basically replacing the document.
It's going to be the same idea here with
comments. If we're using a put request,
we need to take the full comment, make
the changes, and then send the full
comment back. With patch, we can
selectively change attributes of that
comment. So, this really only makes
sense if a comment has multiple
attributes. So we might have a comment
ID,
a post ID, the actual comment content,
maybe it's a boolean whether this is a
reply to somebody,
maybe there's a boolean on whether it's
a pinned comment. And basically with a
patch, we could update any one of these
attributes individually. But with a put,
we're going to take all of the
information.
again we'll change some piece of it and
then we'll give the entire document back
replacing the old one. So logically
we're still updating the data. The ID is
going to stay the same
but the way we're updating the content
is by replacing it completely. So one
very important thing about updates is
that they should be item potent.
And this is a fancy word to basically
say if you execute that update multiple
times, the end result should be the
same. If we replace the document a 100
times with the same information, we
still have the same end result. And
that's exactly why this comment ID has
to stay the same because if we were
giving it a new ID, we're creating a
different comment every single time.
This is important for accidental
resubmissions.
We could submit an update multiple times
and that's not going to break anything.
But if we did a creation, if we did a
post multiple times, we're going to
either get an error or accidentally
create duplicate data. So a post is not
supposed to be item potent. Now this
attribute is something that you need to
enforce in your code. So you can code
these to do whatever you want. You could
make a postdelete data. You can make a
get update data. That's all up to you on
the back end. But these are standards
and a specification for a reason. People
adhere to these because you can have
implicit meaning behind these words. So
when we're talking about updating data,
it should be known to be item potent.
So, we're not going to be replacing the
ID of the thing we're updating. Next up,
we have delete.
It's pretty tough to figure out what
this one's going to do.
Again, it's going to be the same path
because we're referring to a specific
comment.
And that will remove the comment. Now, I
want to show you a couple more examples.
What if we wanted to reply to a comment?
In this situation, we would have a
comment that in a way depends on another
comment. So we would need to know
information about the parent comment.
Who are we replying to? So the way we
would structure something like this
would probably be a post because we're
creating a new comment and then we would
do slash comments
slash id
and then we could have a new path such
as
reply and this could reply to a comment.
And the reason I wanted to write this
one out is because I wanted to show you
two possible different scenarios here.
And either one is okay. So it's not like
the way you do things is 100% set in
stone. You can have design decisions
about the way you structure your API. So
what exactly am I talking about here?
Well, we could now create a comment with
this post or we could create a comment
with this post. Basically, we need to
get the parent ID from somewhere. In
this case, we're getting it from the
URL.
In the case of this post request, we're
not providing the parent ID here, right?
We're providing a parent video that the
comment's going to go to, but we could
still create a reply here if we wanted.
It would just be passed in the body. So,
it might look something like this. The
video was 1 2 3. And then the body would
have
the content of the comment
and it would have the parent ID.
So both of these could work the same
way. In this situation, we're passing
the ID of the parent in the URL 5 67. In
this one, we're passing the parent ID in
the body. Either one of these are going
to need some parent to grab the ID from.
So the only major difference is how you
want to structure the URLs and whether
or not you want this to be nested under
posts or not. In reality, if you're
making a comment reply, doesn't matter
what post it's on because that parent is
unique. Basically, we have a comment 567
and we are creating a reply to it. We do
not care what the parent post is. We
only care about the comment we're
replying to. Logically, it's going to
get us the same result in the database.
This one just has it unnecessarily
nested under a post. Let's go with one
more example which would be to get a
comments replies.
So this might be at slash comments
slash comment id
slash replies.
Same idea here. We don't really care
about what post it's on. All we need is
the ID of the comment we're replying to.
So one quick comment that I wanted to
add here. I would consider each one of
these a different endpoint. So we have
eight different endpoints here. There
might be some conflicting vocabulary
that you run into. So for example, we
could consider all four of these
to be the same endpoint with the same
URL and then just have four different
method options. But I don't think that
makes as much sense because these in my
opinion are unique interaction points of
our app. So even though they're sharing
a path, logically I see them as
different end points. I wouldn't get too
caught up in the vocabulary for this,
but that's just how I tend to think
about it. But what you can say is you
definitely have one path with four
different methods. So all of these in
code
could point to a single function
or it could instead go to four
individual functions.
This is a design decision that is
irrelevant from the interface of the
API. The way you work with the API is
exactly the same. So all of this stuff
gets into how you structure the code.
And I wouldn't worry too much about that
right now. It's just the way you
structure your code. Do you have one
function and then you check what the
request type is the method or do you
have four different functions each one
being associated with the combination of
the method and the URL for unique
destinations. So when we get into
implementation we'll see the differences
here but for now I would just focus on
what the API allows us to do. So this is
our full interface of how we could
interact with comments. We can continue
to think of different ways of how we
might retrieve comments. For example, we
might want all of the comments from a
certain user.
In that situation, it would look
something like this. Get
slash user
slash ID. And this ID always refers to
whatever it is that came before it. So,
the user ID and then we could have
comments.
We're still working with comments, but
we're basically shifting the way we're
thinking about comments. Instead of
associating them under a post, we're now
thinking of them by user. So, we're
changing the bucketing. For a simple
API, you probably don't worry too much
about it. You know, maybe we have just
this many ways to access comments. But
for a complex API, there might be a
large variety of different ways to
retrieve comments. And remembering the
nesting and the structure for this can
get complicated. I'd say starting out I
prefer this structure but I want to
share an alternative which is basically
the comparison of
nested data
versus filtering
and this would be filtering just a large
singular collection. So let's go through
examples showing the differences of
these because when you're designing your
API, you want to know how you're
structuring the API endpoints. This is
also going to get into different ways of
passing data. So this is part of the
path,
but you can also use URL parameters,
query parameters. We're going to look at
those as well. So we've already talked
about nested data.
Basically, when we want to access some
entity but relative to
a collection such as the post,
we can structure our URL like this. And
I don't know why I didn't finish writing
comments, but it's going to look
something like that. Now, for filtering,
we just consider having one giant bucket
of all the comments. And then we provide
additional information to say which of
those comments we care about. So we have
our giant collection of all of our
comments and then we say question mark
then some attribute such as the post ID
and then we set that to whatever the ID
is we are looking for for the post. So
this concept with the question mark this
is called a query parameter
or you might hear URL parameter.
It's slightly different than putting it
in the path. So you can see here we
don't use a question mark here, but
functionally it can be used to achieve
the same results which is changing the
data that we access. So we'll talk more
about the differences between using a
query parameter and using the path in a
moment. But for the sake of this
example, it doesn't matter. All you
really need to know is that we can
provide some attribute to filter. So now
we go from all of these comments to just
a select few that we care about. And
this would be based off of the post ID,
whatever that value might be. In the
notes, I have some additional links you
can do for reading on this, but I'm just
going to summarize when you might want
to do each one of these. So, for
relatively simple data,
or another way you can think about this
would be few access patterns. So, you're
not going to be changing the way you're
accessing comments in a bunch of
different ways. For example, you might
just have accessing the comments by the
post and by the user.
In that situation, using nested data and
going with this approach is pretty
clean. But if the different ways you
need to access the data is vast, it can
be pretty complex to create endpoints
for all the different possibilities.
Instead, you could just group all that
together into a single
dude, I am hungry. Instead, you could
just group everything together into a
single endpoint and allow the user to
filter what they're accessing by. So if
you have complex asset So if you have
complex ax that's freaking tongue
twister. So if you have complex access
patterns you know organizing this
comments by a variety of different
parents. Doing this across multiple
different nestings can be very
complicated and ugly. So you might just
put it all in one and use query
parameters. This choice can actually
affect your code structure as well
because you might have code for posts
and code for users
and code for comments
and you basically have to decide where
you're going to store the code. So there
might be some jumping around or if
you're working in this other pattern
where you just provide in additional
filtering, you can just put everything
inside of a single location for comments
which can really simplify the code.
surface area. You don't have a bunch of
places to jump around to or have to
memorize some system or architecture.
So, which one do you choose? All right.
My personal opinion here is I prefer
this structure where we access by some
parent resource. So, this is what I
prefer. If you have a certain scenario
where you're like, hey, this is just not
going to work for what I'm trying to do,
then you could consider this approach.
This approach would work well if you
need to allow for a bunch of different
filtering capabilities. Now, let's move
on to how we pass data to the backend.
So, we've talked about a few different
options here. We've talked about query
parameters.
We've talked about passing data in the
path. And we've also talked about
passing data in the request body. So,
these are the three main ways of passing
data to the server.
when do you use which? So, let's first
take a look at these two because they
have something in common. They both go
in the URL.
So, typically we'll use a path if we're
using it to identify some data that
we're referring to. So, we have the
resource, but we're not just talking
about a full collection of resources. We
want to access a specific resource. So,
very commonly, the path is going to be
an ID.
So ids usually passed
in the path
and in that situation you don't use a
question mark or an and sign you just
say something like slash123
and this is basically a unique page
or value you're referring to. So for
example, an exact comment.
So the path is used for identifying
query parameters are usually optional
and they're usually used for filtering.
So if you don't provide them, it's just
going to default to everything.
So filtering and sorting
is going to be done with a query
parameter. So if we change the ID, we
change the actual item we're looking at.
If we change the query parameter, it's
still the same path. You can think of it
as the same endpoint. It's just going to
change the filtering or sort.
So that's really important to
understand. Another thing is that with
query parameters, you can stack multiple
in a row. You can do that with the path
as well, but there's typically going to
be additional nesting. So for example,
we could have comments
then the comment ID. Then we could have
replies
and then we could have the reply ID
or whatever it may be. I'm just kind of
making this up as I go, but in this
situation, we basically work our way up
the path to get to the original
entity that we're discussing. And we're
providing multiple IDs so they have
unique names. Changing either of these
is going to change that exact comment
we're talking about. Whereas for query
parameters, we might have something like
cars question mark,
color is blue, brand is Lambo, and
sort
is ascending. And we can be more
specific. We can say price ascending.
and then the backend could still access
all of these values and you use that to
adjust the query
to the database.
You will also see the similar structure
for paged data. So pageionation,
so you might see page five or you might
see a limit on how many you're trying to
retrieve and so forth. We'll definitely
get into that. So that's query
parameters and the path. Both of these
are provided in the URL. And generally,
you do not want to do this for anything
sensitive
because think about it, if you have a
URL, that's a URL you could share with
somebody. It's something that's going to
be saved in your browser history. You
could favorite it or whatever it might
be. It's a unique link. So, if
something's private in that link, it's
very easily going to be exposed and it's
bad for security. So if there's anything
sensitive, it always goes in the body.
So for example, let's say we had a
slashregister.
You can do it the bad way,
which would be slashregister.
And then we'll provide a username
and we'll provide a pass.
and this is a unique URL that has my
username and password that I'm trying to
use for registering embedded in that
URL. This is bad.
Instead, we should just have register
and then we'll have as part of that
request a body
which will then have those attributes.
So, we'll have a username and a password
and that will be formatted in JSON. So,
it looks something like this.
So, this is the proper way to do it.
Anything sensitive goes in the body.
This is also related to if you've ever
been on a website and they have some
form and you hit submit and then maybe
something doesn't work quite right. So,
you hit the refresh button and it'll say
something like confirm form
resubmission. Basically, it's making a
request, a post request.
So forms will use post with all of the
data that you typed in as part of that
body for that request. So when it's
asking you if you want to resubmit that
form, it's basically saying, "Hey, do
you want me to send another post request
to the back end? We already did it
once." But yeah, translation, what does
that mean for you? It means anytime we
have an HTML form, it's going to use the
post
request type for that submission. and
that means any of that data does not get
added into the URL. However, if you're
not doing anything sensitive and you
just want to give the user the ability
to sort and filter, you can make those
drop downs and make the request at the
back end with that in the URL. So, with
this in mind, let's look at what a full
request might look like. You might have
post
SL API/ users. So, this would be
creating a new user. You could also have
it be SLregister. You'll have any other
headers. So you'll often see content
type and this is how you basically say
the notation being used for the request
and this will be
application slashjson.
Then we'll skip down here. We'll open
body
and then any attributes we want to send
to the back end. So here is some example
data all within JSON. This is a pretty
common structure you're going to see.
So, for example, if you're working with
API testing tools, for example, curl or
some of these other tools out there to
make requests to APIs and you're
formatting the structure of the request,
it might look something like this. So,
this is an example of a header content
type, really common one to specify JSON,
but there are other headers you're going
to become familiar with as well. And
this is data that's passed with the
request, but it's different than the
body. You can think of headers as
metadata, which is data about our data
describing how to interpret the data,
for example. And we'll use headers for
all kinds of different things. Now, last
thing I'm going to touch on briefly
because we're going to dedicate a lot of
the next lesson's material on this that
is status codes
or response codes.
So just like there are standard HTTP
methods, you know, get, post, put, all
that stuff, there are status codes which
are included with the response from the
server. So we just looked at how to make
a request, but the backend might give
back a status code. For example, 201.
This is just one example of a status
code. And every single one of these
codes has some implicit meaning. Now you
as the API developer you can send back
whatever status codes you want but
generally you'll follow conventions in a
similar way you do with HTTP methods. So
2011 this will have the text associated
with it which is created
and when a client sees this it can
interpret that message to mean hey we
likely created a new resource.
So this is a common response for a post
request where we're creating a new value
in the database. So there are a bunch of
different codes in the 100 range to the
500 range. Each one meaning something
unique, but there are different
categories. The big ones you should
concern yourself with are the 200 level
which are all kind of like okay things
are working.
300s are redirects,
400's are client errors,
and then 500 are server errors.
So, in the next lesson, we're going to
look at more of these status codes and
how you should interpret those from the
client. What do you do if you get a
certain status code? as well as as the
API developer, how to know which status
codes to use in what scenarios. So
that's what we're going to get to in the
next lesson. As well as once you do all
of this,
we now have a fairly complex
interface to work with our API.
We need some way to describe this to
other users.
So this gets into the world of API
documentation and specs.
Since we're following some standards,
maybe people can get an idea of how our
API works without us even having to say
anything. So, this gets into the world
of Open API and various other things.
So, we're going to talk about all of
that in the next lesson. So, just so you
have an idea of some of the things I
have for the next couple of lessons, I'm
really interested in talking about those
status codes, API documentation and
specs, proper API architecture for
scalability. We're going to look at
authentication at a high level, how it
interacts with APIs, things like API
keys and JWTs. We will also look at
pageionation and how we can transfer a
lot of data to the end user in sections
instead of just giving everything at
once. That and so much more. So, I'm
super super excited if you made it this
far in the lesson. Really appreciate it.
Hopefully, it was really helpful. Again,
just wanted to give you a reminder to
check the playlist. The playlist is
where you're going to find all of the
good stuff and you can just watch it
sequentially. Go through this material
one lesson at a time and I promise I'll
help you become a much better software
developer. So, super excited. I know
I've said that like five times, but it's
just really awesome and I'm really happy
to be doing this. So, thank you so much
for watching. Check out the playlist.
Check out the notes for this lesson and
the upcoming lessons. I'll have a link
down for that below. Check out the
fundamentals course and my other courses
available if you're interested. And with
that, I will see you in the next lesson.
Thank you so much. Peace out.
Fundamentals Course - http://calcur.tech/fundamentals ↪ Full Playlist - https://calcur.tech/software-engineering Lesson Notes - https://calcur.tech/notes ⚙️ Backend Engineering Mind Map - https://calcur.tech/mindmap 💻 System Design Playlist - https://calcur.tech/system-design Timestamps: 00:00 - Intro 01:47 - How is this lesson different? 03:30 - What is an API? 06:18 - Types of APIs 07:16 - SOAP 08:49 - GraphQL 10:06 - gRPC 12:30 - WebSockets 15:18 - JSON 19:39 - Example Collection Following this Pattern / Endpoints 23:15 - GET 24:30 - POST 25:49 - GET by ID 26:52 - PUT 27:27 - PATCH 30:40 - DELETE 31:16 - POST 33:25 - GET 36:22 - Nested Data vs. Filtering 39:15 - Caleb is Hungry 40:50 - Query Parameters vs Path vs Body 44:14 - When NOT to use query parameters (or URL paths) 46:40 - A full request example 47:56 - Status Codes 💯 FREE Courses (100+ hours) - https://calcur.tech/free-courses 🏆 C++ Mastery Course - https://www.codebreakthrough.com/cpp-mastery 🐍 Backend Python Course - https://calcur.tech/backend-python 🥇 Python Mastery Course - https://calcur.tech/python-mastery ~~~~~~~~~~~~~~~ CONNECT ~~~~~~~~~~~~~~~ ✉️ Newsletter - https://calcur.tech/newsletter 📸 Instagram - https://www.instagram.com/CalebCurry 🐦 Twitter - https://twitter.com/calebCurry 🔗 LinkedIn - https://www.linkedin.com/in/calebcurry ▶️ Subscribe - http://calcur.tech/subscribe 👨🏻🎓 Courses - https://www.codebreakthrough.com 🅿 Patreon - http://calcur.tech/patreon-calebcurry