Introduction to REST API Concepts
So this is fine where you are requesting for the homepage and you are writing a text, but then if you remember, we started with an application where we want to work with the products. A product will have an ID, it will have a name, the description, the price, the quantity. Now how we are going to do that? Of course, I can just change this URL. So instead of having homepage, I can say /products. Now that's how you do it for the REST API.
Now whenever you visit a page, let's say if you go to Google and if you search for Telusko, of course you will get all these details here, but look at the address bar. So it is google.com because that's the homepage, then /search because now we have a different path, right? So we are searching and then we are passing a query. So you put a question mark and then you say the variable Q equal to Telusko. So this is what we are searching, right? Ignore the other parts. This is just for the other things. So we can just ignore this. This is the important stuff. So search that's the path and then ?q=telusko. Now this is how you basically do the query.
Now when you visit a page and if you want to pass the query as well, this is the obvious way. But then if you want to search something as a resource, because all the products online or in the database in the back end, they are the resources. So you are requesting for a resource. So instead of saying ?q, there should be a different way, something like this. So let's say if I want to search about products and I will go with the google.com, this will not work, but I just want to show you how it works, how it looks basically. So it is google.com/products. Now it should give me all the products from the database. Okay, that's my expectation. Then if you want a specific product, let's say if you want a product ID with one, product ID with two, then you will say /1. This will give me the first product. This will give me the second product and then so on.
What if you want to add a new product? Now this is where the things will change. Now if you want to add a product, how will you do it? So will you say add here? Now that is not how you do it. So basically what happens is for the fetching, you know, when you want to read, you will use the same link. And for posting as well, when you want to add a new product, you will use the same URL. And now you will say, okay, how will a browser differentiate between when I want to fetch data and when I want to save data? And this is where the HTTP methods come into picture, which we have talked about before. So when you want to fetch data, that's when we are going to use get. So the same URL or the same URI, but the method will be get. If you want to submit something, if you want to post, you will be using the same URL but a different method name. Okay, remember that point because we are going to do that in this particular project.
Setting Up the Products GET Endpoint
So now I want to fetch the products, right? Now before you even fetch the products, you need to have the products. Now, how are we going to do that? Since it's already opened here, so the libraries are already opened. I don't want to open again. So if you see, we have also added Pydantic. Now we have not added it manually. When you ask for uvicorn, you got this by default and this is what we are going to use now. Cool.
So what it basically does, so Pydantic is basically for data validation. Okay. And also if you want to convert your data from the server side into JSON format to send it to the client, we are going to use this. Again, this will make much more sense once we do the coding for it.
The first thing we're going to do here is now since I want to work with the products, what I will do is I will just go back here and say @app.get a get request, but this time instead of saying slash... okay I have to snooze my co-pilot... and then here it will be /products because that's what I'm asking for and I want to say get and I'm expecting all the products, not just one product. And here I can define a function, and all these functions are by default async, so you don't have to mention async. And then I will say get_all_products. If you can be better with the name of the methods, it will be helpful to read. And then this is where you will return the products. At this point, I'm just going to return "all products" just to see if things are working out or not. So, I will just save this. So, when you save, it should reload. And then let's go back here and instead of hitting the homepage, and I'm just hitting the homepage just to check if everything is working, I will say /products. Enter. And you can see it says "all products." Awesome, right?
But then we don't want text as "all products". We want the actual products, and not from the database because we have not done the setup for the database yet. So we'll do that later. So let's say we have an in-memory list. We want to work with it. So there should be a list somewhere here. And let me just create, in fact, you know we are done with this. I can remove this or maybe just keep it there. Why not? Let me just create a list here somewhere here.
Creating a Basic Product Model with a Python Class
But then how will I create the list of products? Because of course this is a list of products but then we don't have a product class. There are different ways of doing it. Of course I can just create a dictionary here by specifying all the values. That's one way of doing it. Otherwise, if you go with the object-oriented way which is a better way here. What I can do is I can create a models, or maybe I can create a product file, but models makes sense because these things are called models, which holds data or which is used to represent any data. So example, if you want to represent all the users of a system. So that's one model. So you can create a user model and this will represent the users because a model will have a name and it will have some properties. Example here, let me get a class, and this will be Product and this will have some attributes. So I will say id of type int, then we can have name of type str, then I can also have a description here of type str, then we can have a type of price which can be float, and then last thing we need is quantity of type int. Okay, so these are the things you need. So basically you can represent the data in this format. So you can create one product which will have all these properties right? And then you can just go back here and create those objects right? So I can use the constructor of it. I can say Product, but then to use the constructor I don't have it here and I can just ask for the constructor, so this is the constructor. I hope this will work, I have not tried this before for this application because we were using Pydantic, but let me try. So I will say id is equal to 1, or maybe I can just pass the value. name I will say phone... Okay, it says Product is not defined. What I will do is I will just import this. So from models import Product. Okay, now there's no issue. And I can add description. So ID is done, name is done, description I'll say 'budget phone'. And then let's say the price is $99. And the quantity, let's say we have 10 of it. So at this point, I just have one product. Or maybe I can add one more just by giving a comma here. So two, laptop, gaming laptop, 999, and let's say we got six quantity of this.
So we got these two products and now instead of returning "all the products" here, I can return the products itself. Right? So what it will do now is when you request for the products, it should return this list. And let's see if this works. Okay, I'm not sure. Let me try. I will say enter. Oh, we got it. So you can just prettify this and you can see we got the data in this format. So this thing works. So basically we can just create this thing and you can return it from here. Now this is one way, right? And this is working, nothing wrong with it.
Enhancing the Model with Pydantic for Data Validation
The problem is in future maybe you want to do data validation. So let's say when you are sending this, when you want to send this from the client side to the server, maybe a client wants to add a new product. And when you say you want to pass the ID, the client is sending an ID, let's say 10, that works. What if the client sends the ID as -1 or -10? That will be an issue, and this will accept it, right? This will not say any problem there because it's an integer. What if you pass a price which is negative? Of course price should not be negative. What if you pass the description of only one character? That doesn't make sense. Why will a description be of one character? There should be at least two words, even if you're lazy. Okay. So how do you do that validation? And that's where we got this particular library called Pydantic which will help you for the data validation. So we have already seen that.
Now, how do you make this a Pydantic model? So it's very simple. You come back in the models and here you can just import. You can say from pydantic because that's what you want to use. We just need one thing from that which is a BaseModel. So I can say import BaseModel. Of course you can take a lot of things from there. So you can import all these things from it and we are going to use some of them later like Field, but here... I'm deleting that part. I will just import pydantic.BaseModel. This is what you need. And then you basically inherit because if you want to achieve that feature, you will simply do inheritance and you got it. You got your BaseModel.
Now you don't even need to create this constructor by yourself. That is done, taken care of. And things you need to change is instead of specifying this syntax, it should be with the variables because that makes much more sense, right? Why do you pass in this format? So id= and then the list goes on. Now instead of typing... in fact this should be name. So instead of typing all these things, I just do have the data ready with me. I'll just copy-paste that. Oh wait, instead of saying copy-paste, I should say code reuse. So paste and we got it. So you can see we got IDs, we got four IDs because we got four products. And then we got phone, laptop, pen, table which is a name. And then we got description, we got the price and we got the quantity. Now with this changes, let me just go back here and refresh. You should be able to see all this. Now if you're not able to see in this format, you just have to download this extension called Pretty Print from Chrome and you will see it in the proper format.
Testing the API with FastAPI's Swagger UI
Now there's one way. Okay, but what if you don't want to use it here? You want some good UI to test it out? You can use something called Swagger. Now in other frameworks, basically you have to add a swagger, but with FastAPI you get this by default. So what you do is you use the same URL but not products. Remove that. So you say localhost:8000 and then you say /docs. Enter. And you got your docs. This is Swagger. Okay.
And now if you click on greet because we have created two endpoints if you remember. We got the endpoint, if you go back to main, we got this endpoint which is for the homepage, and we got the endpoint which is /products. And here we got the first. Now, how do you use it if you are using this for the first time? Click here, there will be an option of "Try it out". Click here and then there will be an option of "Execute". But before executing, make sure that if it is asking for any parameter or not. In this, at this point we don't have any parameters. You can click execute and this will respond here. So it says "Welcome to Telusko tutorials".
Scroll down. We got another one which is "all products". Expand this. Scroll. And you can say "Try it out", "Execute", and it will give you all the products here. Right? Also, if you observe, it returns a code 200. Again, we have not talked about that here but we'll see. Remember this point, the code 200. Just to give you a hint, there are multiple codes available. If something goes wrong on the, with these resources, or the file is not found or something, you will get 404. You might have seen that everywhere, right? So that's a part of the status code. Okay. So this is how you basically fetch all the data. What if you want to fetch one product? What if you want to add a product? Let's see that in the next video.