Learn Minimal APIs in .NET 7

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Welcome to this video course on minimal API with dotnet. Seven. By the end of the course, you will be able to build well constructed minimal API endpoints Brueggen Patel developed this course, he is an experienced and popular course creator and developer. Let's get started. Hey, guys, and welcome to dotnet mastery. My name is broken. And I will be your instructor for this course on minimal APA. APA has been there since a very long time. But Microsoft has launched something new with API, which are minimal API. If you are a dotnet developer, your first reaction would be, why would I need minimal API when I'm perfectly happy with the standard API that are there. On top of that minimal API, as the name suggests, offer less features as compared to a traditional API. And in this course, we will answer all of those questions, as we will explore all the benefits minimal API brings to the table. We have a lot to cover in this course. But there are some prerequisites that you should know, you should be able to follow along, as long as you have about three to six months of experience with C sharp. That being said, let me walk you through on what we will cover in this course, and explore the new world of minimal API. Let's take a look at what will be all the topics that will be covered in this course. First question that we will answer is why minimal API? What is the reason behind the evolution? Does it bring any benefits as compared to the API? And what is the different structure when it comes to an API? Once we answer that basic question, we will understand the basic fundamentals of minimal API's, what files are there, and what is different as compared to API. Then we will be building endpoints with our API. And we will implement custom validations. And minimal API. Minimal API does not support the model state validations that are there in API. So we will see how to validate some things and minimal API, we will learn more about dependency injection, we will inject auto mapper and we will see how to map DTOs in our application. And then we will perform crud operation with minimal API. So you can see there's a lot that we have to cover. Let me get started with all of that from the next video. The main question that comes around all the developers, especially dotnet developers, is why minimal API, we had a perfectly functional API that has been there. And we love that with the controllers, attributes and all the features that are built in. If that is working perfectly, why is Microsoft taking some bits and pieces out of that API, and giving us a very empty template? Which is something like a minimal API? What could be the benefits of having a minimal API? To answer that? Let us consider the scenario. If a developer is coming from a non dotnet background, for example, no GS, in that case, they might not be aware of what is your controller, what are naming conventions for controller, and learning all of that would require some understanding of dotnet. But their main focus is to get the EPA up and running quickly, without learning all the fundamentals of dotnet. Programming. That is one of the reason behind development of minimal API, we want to have the minimal code that is needed for API, rather than adding controllers. Because if you think about that, when we have to build an API, in other programming languages, or even in dotnet controller is not something that is always needed. It has been there because previously we had MVC, and we had controllers. So Microsoft thought about unifying both of them. And that is the idea behind controllers. With minimal API's, we do not have the controller. We keep everything simple and straightforward in a class file. Now, when we learn minimal API, everything will typically be in a program.cs class file. But then developers might think that my code will look ugly. If I have 50 end points and all of them are in one file. Do not worry. We can of course separate them out in different files as well. But me point here is we don't need a controller. Now since we are not adding extra features like controllers and other overhead, which is not always needed for an API, we gain performance improvement, which takes higher priority in some situations. So if we are keeping things minimal, then the performance of our API will increase. Microsoft is investing time in minimal API. And it is adding more and more features. Like previously, there were no filters, but they have added filters with minimal API in dark net, seven, and much more. With all the new features being added minimal API are gaining more and more attention, especially in scenarios like microservices, where API are not that intensive. And efficiency plays a critical role. With that overview, I'm sure you are excited to learn minimal API, and what they have to offer, what is the syntax, how we can perform crud endpoints and much more. To get started, we need to create a project that will use minimal API. So I will open Visual Studio 2022. And we will hit Create a new project. In the templates here, we will search for the regular API project. And we have the ASP dotnet core web API using C sharp. Let me hit the next button here. And we need to give a project name, project name, I will change that to be magic biller underscore coupon API, we will change the location where we want to save the project. And the solution name, I will call that minimal API demo looks clear. Let me add that. And we have more option. The framework here we will be using dotnet seven authentication type, we will keep that as none. But later on in the course, we will be adding authentication and authorization configured for HTTPS looks good. We do not want the darker support. But the main thing here is use controllers, we have to uncheck that if they want to use minimal API. Because if you keep this checked, then it will create the regular API project with controllers. We do not want that. So we will uncheck that. And that will create a minimal API, we will enable the open API support. And lastly, we do not want to use the top level statements, we can keep that as unchecked. With that in place, let me hit the create button with the default settings. And great our project is created here. And we have our minimal APA right here. Before we go through the files that we have and minimal API here, let me create a regular API project back then we can compare and see what is different. So in the solution here, we will add a new project. And it will be an API project. I will conduct regular API sample, let me add that we want to use the controller. So make sure that that is checked. And we will hit the Create button. Perfect that is created. Now that we have a minimal API and a regular API project. Let me compare to see what is different. You can see in minimum API project, we have properties folder. Same thing is there in regular API. And there it is just the launch settings dot JSON file that basically tells that which port it should use. And it has a profile for Kestrel as well, that stays the same. Because no matter if it's a minimum API or a regular API, it still needs to run the project on a URL. And outside of properties folder, we have App Settings dot JSON, that is also constant input of the files. But other than that, in minimal APA, there is just one file, which is program.cs. Whereas in the regular API, we have controllers, we have program.cs, and the weather forecast model class as well. So going by the name minimal API has actually minimal file, only program.cs. And that file has all the logic. Now let me set the startup project as part of the project here. And let's see if the output is any different. And great. We have both of them up and running here. Let me add them side by side. and perfect. We have both of them right here, we have the regular API. And here we have the minimal API. From the look and feel, you can see both of them looks the same. We have one endpoint weather forecast that looks good in the swagger documentation, we try that. and execute, everything is the same, we have the same response. And everything looks the same. So from the look and feel, or the Functionality wise, minimal API is not that different. Now, of course, as we proceed with the course, that will be some features that are not yet available in minimal API's, or they are not planned to be added. But the base functionality that we can see right out of the box looks the same. But minimal API has only one file, the regular API has controllers, program.cs and weather forecast. So that gives you a good comparison between the files that are present in minimal API as compared to the regular API project. Now, as a prerequisite to this course, I hope that you have a basic CRUD functionalities of what API is responsible for. If not, I have a free course on YouTube that you can take to get familiar. But here in the regular API, we have a controller endpoint, we have the API controller, and we have the HTTP GET action method. That will be the endpoint, which will be invoked. And here we have this model weather forecast. That is right here included, that is the regular API for you. But now that we open the only file that is present in the minimal API, which is program.cs. Now, if I switch the funds here, you will notice that add controllers is not present in program.cs, after minimal API. And that makes sense, because in minimal API, we do not have any controllers, then the swagger endpoints, they are present, because we want the swagger documentation with our minimal API as well. After that, we have app dot build. And that is the same where we are configuring the pipeline. We have swagger documentation for development, we have HTTPS redirect authorization, map controllers and run. But in program.cs, we don't have much things. We have swagger, we have the HTTPS redirect. And that's about it. We just have the app dot run after that. So we do not have any authorization or map controllers that are added by default. The main idea behind minimal DPI is to keep things super simple. If you have the requirement to add those, you can of course add them. Like in a minimal API project. It is of course possible to add a regular API with controllers if you want that. But that is not the main purpose of a minimal API. It is there to keep things super simple. So if I examine the program.cs, we just have apps that run with HTTPS redirect and swagger in the request pipeline. Now, the main question is, how will it work? Before we check that, let me remove the regular API project that we added. I only added that to compare the differences. So you get an idea. We don't need that anymore. With that, we only have one file here, which is program.cs. Open. And that looks good. Let's continue from the next video. When we run the project here, we notice that there is one endpoint, which is weather forecast. But where is this endpoint, we do not have any controllers or any other file. So basically, that endpoint will be somewhere in program.cs. If you scroll down here, we have the map get right here. That endpoint is mapping a get request. And we have the route right here. When we expand that, you can see there is a little code right here. And this defines what needs to be returned back when this endpoint is called with an HTTP get request. We also have written in and with open API that we will come back to later on. But basically, this is how mapping is done. And if any model clauses are needed, in the default template, they are added right here, this is a record and we have the summaries array right here. So all the calculation on what should be returned when the endpoint is invoked. It is right here in the program.cs class file. Now that will bring up lots of question. If you are coming from a regular API background, and do not worry, we will answer them one by one. But in order to get started, let me remove all the code that is added here for the endpoint. We want to start clean here. So perfect. Now, our program.cs only has the swagger endpoints here. Pipeline also has the Swagger UI, HTTPS redirect. And that's it. No controllers, no authorization, nothing else is present in our project or pipeline right now. Like me run the project, we should not see the endpoint that was there before. And we see no operations defined in the spec. So we do not have any endpoints in our API. And everything is clean right now. Let's continue and add our first endpoint in the next video. The next section that I have is all about the API basics. Like what is a request? What is a response? What are HTTP verbs, and so on. Now, these are the fundamentals of API. And it does not matter whether it's an API or minimal API. So if you are aware of the basic fundamentals, like POST, PUT, patch, delete, and what is a request response with the API, feel free to skip this section, and move on to the next section, where we will start the programming. But if you want a refresher, let's do that. From the next video. We have the big question, what is an API, the definition for an API is Application Programming Interface. But that is not explanatory. In simple words, API is responsible for transmitting the data. Or rather, it is a way for multiple applications to communicate with each other. In today's technology driven world, we are connected like never before. API is the critical engine behind sharing information across multiple application, and programming. APA is responsible for getting a request from the client, and then sending a response back to the client based on the request, and the request and response that will be multiple of them. And it continues. So basically, if a client is looking for some data, it would ask API by sending a request. And then EPA would return back that data in form of a response. The model that we see here is the website model. What is different between that and an API, what makes an API stand out is it is not just the web browser that can call an API, many other application can invoke an API endpoint. So let's say you have an API that can be consumed by a web application, your mobile application, or Windows application, and much more. Not only that, you can expose your API to other clients. And we have more examples of that. But before we go into those details, the example that we see here is related to programming. Let me simplify that by going to a real world scenario. Let's say we go to a restaurant, and we have menu on the table. And after a lot of thinking, we finalize on what to order, Chef is also ready to start cooking. But the missing link here is to tell chef on what we want. That is where server comes into the picture, which is basically like an API server will be responsible for taking orders from the table and telling chef on what needs to be prepared. And that would basically resemble a request. Once the food is ready, tensor work will pick that food and deliver that back to the table, which will be a response. So here you can see how server is acting like an API, where it is taking the request and then it is delivering back the response from our kitchen. Now, let me show you one real world scenario, which many of you would have experienced without realizing that it is driven by APA. Let's imagine we are going on a vacation and we need to book tickets by an hotel reservation, like myself, I'm sure you want the best deal out there. But it will be a huge pain to go to every airline website to see what is the price of that ticket for a specific date. Right than that, you would prefer going to a website like kayak.com, Expedia or Priceline, where they will display the rates for multiple airlines. And you can filter the best deal from their website. What happens in the backend on kayak.com is American united and spirit would have exposed an API kayak.com will be calling those API endpoints based on date, origin and destination. And it will return all the response from the individual website. Whatever response it returns from those website that will display all kayak.com. So basically, American United spirit and other airlines will have their own API. And kayak will be calling those API endpoints to display the connected information in one place. Same thing happens when you compare hotel rates on Expedia, Priceline, or other websites, where they get information from multiple websites. So as you can see, API is the main superhero between connected services. In today's world, we take the web for granted. When we open a browser and we go to a web page, we just expect it to open up and work. That is the default behavior. But what goes under the cover is a black box. In reality, many things happen between when you search for something on the browser, and what you see on the screen. Once you hit an Enter button. Let's talk about what happens when we make such a request, we will consider an API in our scenario. For example, when we go on a laptop and search for something on google.com, or any other web page, it is going to make a request to some remote server. Now this request is actually a text document. So basically, it will send a text document to Google server. And this document will contain three information. First, it will have a word, which defines what is the action that server has to take. Then we have headers, which have information about the request itself. And finally, we have content, which is an optional field. As an example, let's say you want to create something on the server. So in that case, the HTTP word will be post. And we will learn about this words in just a minute. But when we have to create, we will be using post. And that is what we have in HTTP worm. Inside header, we might have information about the content length, that the content here will be nine byte. And finally, we are sending magic API as the content. Let's say that is a string that we want to create. So all the data will be inserted content. Now, this is just an example. But this gives you a brief idea of what will be there in the text document. When the server gets this request, it can either recognize that as something it can process, or it might reject it, because something might not be valid with the request. But in both cases, it will send a response back to the client. And in that response, we will have three items. Again, we will have a status code, header and content. When client makes a request, server processes that and sends back a response response is also a piece of data. You can think about that as another text document. The status code here basically defines the request that was made, was it successful, or did it fail? Based on the different failure scenarios or successful scenarios, we have different status code. In our example, we did HTTP POST request. So it might send a status code of 201, which stands for created we will get to know the status code very soon. So do not worry. Right now it says 201 created in the response status code, which means I have created the resource that you have asked me to. And I'm going to return you some data along with certain content type we are saying that the data that I'm sending back is of type text. And then in the actual content, let's say the server is sending back magic API. When important thing that you have to remember is server itself here is stateless. Stateless basically means that server will not remember things. And what I mean by attack, a server will be getting multiple request. Once it processes that request and sends a response back, it forgets about that request. Because if it was remembering about all the request, then you can just imagine on how massive the memory consumption will be. And the disk will be overloaded with the data of all the requests that it received. So always remember that server will be stateless. Based on what we have seen, we have a request that is originated from the client, and we have a response. The request will have word header and content and response will have status code, headers and content. In the next video, let me dive a little bit more into what exactly is in request, what is HTTP web headers, content. And similarly, in response, what a status code headers and content. Let me do that. In the next video. Let's understand the request object that we have. First thing in the request object is work. And these are HTTP words are action. They basically define what is the action that needs to happen. If you are working with some data, you might want to create, read, update or delete that data. We have specific word, which defines what action is needed for the request. Most common of the HTTP word is when you want to fetch some resource or a web page, which basically means that Hey, get me something from the server. So that basically means fetching some data. And that is most common. After that, we have post which is used to create or insert a new resource. Whenever you want to add a new record or anything on the server, you will be using the post request, then we have put, which is used to update a resource that already exists on the server. Sometimes we also use patch, which basically means that please do not update the whole resource, I only want to update a part of that resource. For example, if your object has 100 properties, and you only want to update one of those properties, you will use batch in that case, put basically contains the complete resource and patch works on one part of the resource. Then we have delete, which is pretty obvious. It basically delete the resource from the server that are more HTTP verbs, but they are very rarely used. And typically, we always play with the five that are most common. So that gives you a brief idea of HTTP verb, and what action they are responsible for. The next part in the request object is the header. Headers are a set of name value pair that are metadata about the request. First one you can see is the content type that basically answers the question on what is the content type of the request? Is it a binary data? Is it a JSON file? Is it an XML file, or is it a plain file, then we have content length, which basically defines the size of the content. In request microdata, you might also have authorization, sometimes request needs to be authenticated. In that case, the authorization header will be populated with a bearer token or whatever authentication you are using. We also have accept type, which defines what kind of a request is acceptable, like JSON, XML, and so on. And then there are literally hundreds of headers. You can also define your own headers if they are helpful in your situation. But headers basically have metadata of the content and request. And finally, we have content. Con content is an optional field. Here, we can pass the content that the server will require to complete the request. It can be a JSON object, which can later be deserialized by the server to process the request. It can also be blobs that have to be created or updated. If you are trying to retrieve a resource, then you will be using HTTP get word. And get will never have the body because we are requesting the API to return something. And the API does not expect any data in the request. But if you're posting or updating, then we might have to pass the object that needs to be updated or created. That way the EPA can extract that object from the content to process the request, this is a brief overview of the request object. Typing said, let's analyze the response that we get from the API in the next video. In the last video, we saw the request object, which had work headers and content. Now let's examine the response object, which is basically once the request is received by the server or API, it will process that it might be accepted, it might be rejected, failure or success. Whatever it is, it will return back a response. The first thing that we have in response here is the status code. status code is simply a number that represents on what was done on the server, and its final result. But all the numbers that are returned have been arranged in some brackets. And they are very critical, like 100 to 199, or informational. You will rarely see the 100 status code, but they do exist. Most common one that you will see is 202 299. Any status code in that range basically means that the request was completed successfully. 200 is most common, where it says everything is okay. And everything is done as requested. That next we have to work one, which means created. If you are posting something, then you can return it to someone that the resource was created on the server that defines 201. Then we also have war for no content. This is more common when we are updating something. Because when we update a record, we just want the user or client to know that the update was successful. And we do not want to pass the updated record. In that case we will return to work for which basically means no content. But as you can see, it is within the success bracket. That means everything was successful, but we do not have any content to return. Next bracket is 300 to 399, which are typically used when there is redirection involved. After that we have 400 to 499, which relates to client errors. What I mean by client error means that there is an error in the request that was sent, you may not have included a query string or some part of the URI does not exist. The famous one that you would have seen on websites is 404, which represent not found. So let's say you are accessing an endpoint that does not exist. Like let's say you want to retrieve something based on an ID, that Id does not exist. In that case API might return back for or for that the resource that you are looking for does not exist. We have 400 status code, which stands for bad request, which means something in the request was not as expected. And then finally, we have status code within the bracket of 500 to 599. And these are for internal server error, like the 500. Here is internal server error, which means that errors have been encountered on the server while processing. So basically, the request that was sent to the server was a valid request. But when that request was being processed by a server, let's say an exception was thrown internally. And because of that, the server could not process a valid request. So that time it will send a 500, which means there was some error on the server side, and nothing was wrong in the request. You can see status code plays a very important role in the response object. Because based on the status code, the client will be able to know if the request was successful if it failed, and if it failed, what was the reasons? So on the next we have headers in the response object as well. And they contain metadata. But this time, they will have metadata about the response object, like what is the content type, what is the length of the response content, until when it will be valid, and so on. Also, similar to the request object, we have content in the response object as well. And that might contain JSON result, it might contain blobs, HTML, whatever the response server has to send, that will be in content. So typically, if we have to compare request and response, both of them will have headers and content, but the main thing that differentiates them here is the word and status code. Request has the word which defines what action needs to happen. And response has the status code, which defines if the request was processed successfully, if there were errors, and so on. headers will be different for request and response. But typically headers defined metadata, and content will have any content that needs to be passed with either request or response. So I hope this gives you a 10,000 feet overview about request and response, and what is included in them. That being said, let's continue from the next video. Now we know the basics about HTTP worm. But let's take a look at some URL and get some theoretical idea behind the HTTP worms. Most common HTTP worm is a get request. Let's assume we have a table where we have a list of all the coupons in our website. That table is pretty simple. It will just have something like a coupon name, what discount we get and some other details. But we want an API endpoint if someone calls that it should retrieve all the coupons and send it back. Now this is more like a read request, because of that the HTTP worm will be get. And then we have the API path, localhost 7001, whatever your domain is, that's okay. But after that, let's assume we are giving that a route of API and 10 coupon, we cannot have any other parameter here. And this basically, the action we want is to get all the coupons. So in the request party, we will not pass anything here. But in the response that we will get from the API, it will give us a list of all the coupons from our database. So that is a get request. Now another type of cat request is where we are passing an ID of the coupon. At that point, the HTTP word is still cared for. Because there is an ID here, we know that the user only wants one coupon request will not have any body, but the response party will have the single coupon that user wanted. Now, of course, if the ID is invalid, we will not send any response party with the coupon. But if that is valid, the response party will have a coupon. These two are basic request in HTTP kit. But let's say if a user or admin wants to create a new coupon code, in that case, our HTTP word for the request will be post, and we will use the same URL. Now the way it will differentiate between the first URL and this one is the HTTP word will be different. If the word is posed, the API will note that that means that we will be creating a coupon. So API automatically differentiates between the verb even if the URL are same. So for post, we will create a coupon. And when we are creating a coupon, if someone sends a request, we obviously need the details about that coupon. Like on the website, someone will write the coupon name, what is the discount they want, and then the admin will hit the Create button. At that point in the request, we will get all the coupon details that the API has to create. So API will create that coupon when it receives the request. And in the response, it could send the created coupon or a route to that created coupon. Now, if everything here does not make sense, right now, do not worry. I am just giving you a basic idea of API and its action. Next action or HTTP word that we have is book and that is to update any existing coupon. In the route here, when we are updating, we can pass the ID of the coupon that we want to update because of the HTTP port word and request we will require the coupon details that have to be updated. And once the API updates the coupon typically does not send any response like the updated coupon. If you want however, you can send it but that is not the typical route that is taken. And finally, we have the Delete HTTP verb, where again we will pass the ID here. Action we just need to delete that coupon. It does not have any request body or a response. Based on the ID that is there in the parameter. It will delete that coupon and return an okay request. That means everything was completed successfully. So what we have seen here is what will be in the request party, or what we will get in response based on the HTTP verb, and something in the URL, whether we require an ID, if we don't do that, and so on. So this should give you a brief idea about what each request or rather HTTP word is responsible for. Now, again, this is just a rough idea. Once we start programming, everything will start making much more sense. That being said, let me continue from the next video. Let me add our first endpoint right here. One thing that you should remember is all the endpoints, we will have to configure that before the pipeline ends. Because in a traditional API project, if you remember, we were using something like f dot add controller, and that was adding controller to the pipeline. Here, we are not adding the controller, so all the endpoints of your API that you want to add, you will have to add that before app dot run. Right here, we will say app dot map. And you saw before, we had something called as map cat that actually maps or rather tells that this will be an HTTP GET action method. If you examine the parameters, here, we have a string with a pattern and a delegate handler, I can define the route of this API. So we can say something called as hello world. And watch that return. You can keep it simple. And we can just return back hello, word like that. That will add an endpoint in our minimal API. Let me run the project. Perfect. You can see we have that route here. We can try that out. execute that. And we have hello world. If you want to test that using swagger, or it is an HTTP GET, we can directly paste that. And we see the word right here. Perfect. You can see our endpoint is working as expected, and how simple it was to add an HTTP GET and point right here. Now, that would make you curious. And now you will be like, can I have an HTTP POST endpoint? Of course you can. We just have map post here. We can call this Hello World, too. And we can return hello world to Now typically, an extra day began, you will have something in from body where you will be creating a record. But we are keeping things super simple, right now. Let me run this and see if that works. Perfect. We have the post here, write that out. We don't need any parameters. And perfect, we get the response. That looks great. If it was an API project, there is no way that you can add one line and the endpoint will be added there. But here it is pretty simple. Similar to map get, we have my foot and pap delete. So I agree if the app not map here, and we scroll down, we have to delete. We have bad POST, PUT. And where is the get right here. So you can see we have all of those basic methods of the API endpoint. With that in place, let me continue from the next video. Right now we are adding or returning what we have in a single line. But what if you have a complex calculation that your API needs to handle and unique multiple lines for that, that is simple as well, we will remove this and we will add a curly bracket here. We can perform all the calculations right here. But to keep things simple, we will just return as a word right now. Perfect. This will work exactly the same. Let me run that. And show that. Write that out. Perfect. That looks good. Now right now you can see it returns 200. Okay, that is the response that we are getting from the server. But let's say there are some errors here. And we are returning an exception here. But that time also it will return a 200. Okay, right now there is no way to tell that, hey, this is a bad request or something went wrong on the server. So basically, we have no way of controlling what is the return type for our API. Alright, now, that is also done everything that we want to return inside results dot end we have the endpoints for the status code. We have accepted, created, not found, bad request and all of that right here. Let's say we have a bad request here. And inside there, we are seeing that there is some exceptions that is being thrown. Let me run that. Way. We'll try this here. And perfect. Now you can see our API is returning a 400, which stands for parrot request. If everything was good, right here, we can directly return results dot Okay, inside there, we will pass the hello world. If we want to keep that in same line. If you want multiple lines, you can add the curly brackets and do the same thing with results start. Okay. Let me run this and make sure that works. We have enclosed here examined the response that is 200. Okay, so perfect. With that, let's continue from the next video. That returned results here we can toggle on whether it is a good request or a bad request. But in an API endpoint, sometimes we have to pass something to the parameters. That might be a front body, or let's say an integer or a string parameter. to parse some data. When we have to use an integer, typically, in an API, we have to write the integer name here, let that be an ID. That stays the same. But right here, we will see that we are expecting an integer ID. And we don't want exception, we will save okay here. And we can print the ID. And we'll just say plus here, let me run that. Perfect. You can see it expects an ID, Swagger UI is displaying that. Let me enter 11 and execute. Perfect, we have the correct response. If you enter a string here, swagger will display the error message. It has to be an integer, but we can open postman here, paste that URL, and see what happens. We see the exception here failed to bind the parameter integer ID from this. And you can see the response type is 400. Bad request. But if we are passing a string, then this should actually be a 404 not found. Because the get endpoint that we have is the endpoint with an integer and not a string. How do we fix that? Fixing that is super simple. Let me go back to the map get here. If we go back here, and we explicitly say that this ID will be an integer only, that should solve our problem. Let me go back to the postman. And let me execute. And perfect. This time, we have the 404 not found. And that looks good. So we can be explicit with the parameters similar to what we had in the API project as well. We have seen some basic examples of adding the endpoints. But let me work on something that is close to a real world application. Let's say we want to perform CRUD operations on a model and that will be coupons. So, first, we need to create a model for that inside solution, we will create a new folder and that will be models in there we will right click add a class file, I will call that as coupon and inside there I will create six properties, we will have idea of the coupon we will have the coupon name, what percentage discount will that coupon give and if that coupon is active or not, I will also add another level created and last updated. Now if you are new to dotnet six, and if we examined the project here at a project file, you can see in a label is enabled by default. This basically means that if something is not you have to explicitly define that property will be now but to make things simple or if you are working with a legacy dotnet application or dotnet core project that is an older version, this must be disabled, even if you upgrade that because many times personally I have seen when I have upgraded Get the project to latest versions of dotnet core. And if this nullable is enabled, API endpoints are breaking, because previously, we did not explicitly define every endpoint that it is an allowable endpoint. But now if that is not defined, it does not find that endpoint. So to be safe, you can disable the nullable in the CS proj file. But right here, we have explicitly said that created and last updated is nullable. So we should be good. But to avoid any issues or confusion, we have disabled in the level flag inside the project file. So our class here looks good. Next, we need to create a store that will have a list of coupon. Now down the road are typically in a real world project, you don't have a store, you have a database where you manage or update all the coupons. But to keep things simple, for now, we will add a coupon store. Let me create a new folder, which will be data folder. And in there, we will add a class, which will be coupons store. Inside there, we will add a static property, which will be coupon list that will be released off coupon and we have just added two coupons in there. We will make this a static class as well. Thankfully, we do not have to create object every time. Perfect. So our coupons total can now be accessed with our new API endpoints that we will create in the next video. Now that we have coupons store and coupon model, it is time to add the first endpoint that will retrieve all the coupon. So we will say tap that map get endpoint and the route here. Rather than calling it coupon. I typically like to add API in front of that. So we will say forward slash API, and then coupon that will retrieve all the coupons. We will be using the delegate here. And what he will return is results dot okay. And inside there, we have to access the coupons store that we created. I will add the USING statement. And in there we have the coupons list. That is what we need to return. With that in place. Let me run the project. Perfect. Let me try this out here. And great. We can see both the coupons in our coupons store. Now right now, even though we have one line here, let me add a curly bracket here and break this out. Right here, we will add a return statement. And we are missing the closing semicolon. Perfect. We have the multi line function right here. Great. So our cat endpoint looks good. Let me continue from the next video. We have the endpoint to get all the coupons. But what about when we have to retrieve an individual coupons based on the ID, we can create that as well. We know how to retrieve the ID. So right here, we will expect an ID and that will be integer, we will have the same name here integer ID. And then when we are returning back the result here from the coupon last, we can use first or default to retrieve the record based on the ID. So if you.id is equal equal to the ID, perfect, let me run the project. We have ID one and Id two. Let me try the ID two here. And great, we get the 20 off. So our coupons store is working as expected, we have to ID and that retrieval is working. Next what we want is post PUT and DELETE action endpoints. So let me just add them for now. We need the post here to create a coupon and when we post we will use the same path API forward slash coupon. Now of course when we post in the handler here we will receive a different object but we will worry about that later on. Okay, let me copy this and paste it two more times here lightmap post we have my put here and we have the map delete. Now in post and put both of them we will receive the coupon object and the parameters that pay we can create yet are added the coupon, but when we delete here, we will receive ID. So let me copy that. And we will get the ID right here. Perfect. So these three looks good. In the next video, let me first work on creating a coupon. Now we want to create a coupon. When we create a coupon, we typically receive a coupon object from the party. So getting that is exactly same like we do in API project, we will save from party in the parameter here, and we will receive a coupon object, let me call that coupon. And we will add USING statement for our model. Now from body requires a USING statement which is in Microsoft dot ASP NET Core dot MVC. But once we add that it will know that a coupon object will be passed from body when the post request will be called. Then before we create, we typically have some validation, we will add a validation here that if the coupon ID is not zero, or if the coupon name is empty, that is an invalid ID or coupon name, because when we are creating the coupon ID must be zero. If it is something else, then that is not a valid ID. Because ID is something that typically the database, all the code is responsible for adding. But we don't have any database right now. So now we need to populate the ID. How will we do that? We will keep things manual, we will say coupons.id is equal to inside our coupons store, we have the last third, let me order by descending, so we will get the maximum ID at the top here, you close to a u.id. And on there, we will retrieve the first record, they have to will retrieve the ID of that record. So here we are getting the maximum ID of all the records that we have in our coupon store. So that will be two right here. On that too, we will add one. That means that we are manually setting the id plus one by the maximum ID in our coupon store. And before I add the ID here, I want one more validation, I do not want the same coupon to be created again. So we can add an if condition in our coupon store and try to retrieve first or default, based on the name that is being created in the coupon. I will use that to lowercase that we will make coupon case insensitive. So if the code already exist, we return part result. Coupon name already exist. Pretty good. Next, we have the ID here. And then we have to add it to our coupon store dot coupon List dot add we will be adding coupon perfect our create or post is complete here. Once we do that, we can return back with those dot okay. And there we can return the coupon that has been created. Perfect. Let me run and see this in action. Only parameter that we have to change here is name let me call that 30 off. And it is a 30% discount ID we can leave that as zero because if we go back to our application, we are changing that Id based on the ID that we have in our coupons store. The maximum one is two. So next one will have the ID of three the ID here we can remove that and it will still work because it will automatically populate the ID. Let me remove that and hit the Execute button will scroll down and perfect in the response body you can see it is three. If we go back and we try to get all here. Now we have three coupons. But again, this is a temporary data store. When you restart the application, there are coupons stored will be back to the first two which are the defaults that we have. So keep that in mind. We are not storing this in database. It is temporary and in memory. So perfect. Our post is working as expected. Let me continue from the next video. Before I work on put or delete when we have the post Here, there are quite a few things that are missing in our API endpoint that we typically do in a dotnet. core API. One thing is rather than returning an okay, in HTTP POST, sometimes we return the created at route. Now, of course, we can return the created. And that is completely okay. Before that, let me show you how to use the results dot created. When we use created, we have to write the route where this is created. And then for the value, we can pass coupon. So the URL here, let me use string interpolation here. It's API forward slash coupon, and then we need the ID. ID will be inside coupon.id. And let me run that we will create a new coupon, we will update the name and percent. And let's go down that is created. Here we have two one. And in the location, we have API coupon and three. Let me go to the local host URL here, we will add local how localhost and then we will paste the route that we copied, and grade that retrieves the appropriate coupon with the correct name, and percent. So created is working as expected. But what if we want to use the created add route? For that, we actually have to give this cat some route name. How to do that with minimal API. After the map CAC, here, we have something called as with name. And then we can provide name of this endpoint. So right here, I can call this endpoint as get coupon. And then we can use that name. The first one here, let me contact s cat coupons, the HTTP POST, we will call that as create coupon 10 Rather than using created, let me copy this commented out. And we will be using created at route. Inside there, we need the route name as the first parameter. That is character coupons. Next parameter here is the ID. So we will create a new object. And we will say ID is equal to coupon.id. And finally, we will pass the object that looks good. Let me see if that works. We will post again, it will create an ID three. Let me try that. And perfect. That looks good here in the location, we have the complete URL, as well as the endpoint. If you copy that, and cry that it should work. Perfect. So with that, we know how to use the width name to give our endpoints a name. And then we can use that in something like created at round. Now we have the names for our endpoint. But if I run the project here, and if I look at the swagger documentation for HTTP post here, the response type here, it says that it will only return a 200. Okay. But that is not correct. If we go back here, if the ID is not zero, let me try that here. So we will keep it as three execute this, we get a 400. So basically, our endpoint can return a 400 bad request. But in the Available responses in the Swagger UI, it only thinks that it will return a 200. Okay. And that is because in a traditional API application, we have the HTTP response. And we explicitly say that these are the possible status code that our endpoint can return. How can we define that with minimal API for that on the map post here, where we have the with name, we also have something called as producers. And here we have generic when we can see the model that will be produced. We know we are creating a coupon here. So I can say produces a coupon and then what will be the status code. If everything is successful, that will be 211. We also have a bad request here. The way the ad produces and when it is a bad request. We do not have any model so we will just add a produces 400 bad request If you have other status code, you can also add them right here. Let me copy this, and we will modify our individual kit and get out. Now this one will produce a 200. Okay, it does not produce bad request. So let me remove that. And to Hungary, the first one here will not be a coupon, it will be an IEnumerable of coupon. Perfect. Let me restart the application. Right here you can see we have an array, when we have the individual GATT, we do not have the square bracket. But let me open the post here. And there we have 201, we have the correct model, and 400 bad request, we do not have any model in that. So that way, we can explicitly define what will be the response that will be produced. On top of that, you can be explicit on what this endpoint will accept. Right here it is expecting a coupon. So when we have the with name, we can also a dot accepts that expects a coupon. And there you can explicitly write the content type. Like if you want to limit application JSON, you can see that explicitly right here. With that, let me run the project. Once again. We go to post here, and everything stays the same because we have the request party. But that is more documented. Can now the swagger can read, what are the exact things that it expects, what it produces, and the models as well. So perfect. With that our three endpoints that we have, I believe we have good documentation so far. Let me continue from the next video. When you work with a dotnet core application, Dependency injection is a very critical piece. And minimal API supports that. So don't panic. The first example that we will see is the built in ilogger, that comes with an API project. To see that in action, let me create an API project because I removed the one that we have here, we will create a sample. That's okay, we don't care about anything else here. And perfect. Here. If we open our controller, you will notice we have an ilogger on there we can use to log something in the console window. This ilogger is being used with dependency injection, and it is available by default. So how can we use that in our minimal API project? Let me log something when we are getting all the coupons right here. In the parameter here, we can explicitly say that we need an ilogger. So if I go back to the API project, let me copy what we were passing in the constructor here, we do not need to create a private read only, we can directly retrieve that in parameter like that, you can see ilogger is being detected, but it does not detect the weather forecast controller. But right now, we are in program class here. So we can see that right here. And with that the logger has been injected, I like to use underscore for all the dependency injection that we have. We will add underscore logger. On that we have the lock method, log level, we will say information. And we will say getting all coupons. Let me run the application and see if that works. We are using Kestrel to run the application. So when you run the project, you will actually have a command line window like this that is open. Make sure to open that if you do not have that and if you're using IIS express to run that you can also go to the output window and we have debug here. Let me pin that as well. Perfect. Now, if I go back here, let me try to get the coupons. We execute that and perfect. You can see in the logs here and go to places in the console window if that is open, if not we have the output window here we have the log which is getting all coupons. So that way you can see how Dependency injection is already built in with minimal API's. If you are injecting something that is not available, you will of course have to inject that where we have If the add services right here, and it will basically be before line 14, where you are calling the builder dot build. So where we have the builder dot services, you can register new services, and in the endpoint, you can directly get the implementation. So with that basic example of dependency injection, let's continue from the next video. Now, let me run the project here. And I want to show you when we are posting here, we do not want all of these properties, we only want name present and is active. So in a typical API, we do not expose the complete object, we only expose the DTOs for that endpoint. So for create, we will add a DTO in our project. In Models folder, let me add a new folder for DTO. And in there, I will add a new class, which will be coupon create ETL. Now that I only want three properties, so let me copy them and paste those right here, we will go to our endpoint here. And when we are creating from body, we will only retrieve the coupon creativity that we are only getting what we want. And I will call this coupon underscore C underscore DTO, which has coupon create DTO. Let me change the names here. We need the ID as well. Now in our coupon create DTO, we do not have the ID, we can remove this condition. But when we have to assign the ID, we actually have to convert this coupon create DTO to coupon DTO. So if you want, you can manually do that coupon is equal to new. And we can do the manual mapping like that. Once we do that, we can add ID on this coupon add that to our coupon store and we are returning back the coupon. Now rather than coupon here, let me add a new T to that we will call that as coupon TTL. The reason behind that is let's say we never want to show when the coupon was last updated. So in the coupon DTO we will not have that property and we will return back the coupon DTO so produces here will be a coupon DTL except we will change that to coupon create DTO and when we return back, we will basically have to convert this coupon to the coupon dt. So right here, we will need the conversion again like that. And perfect. That looks good. We will return back the coupon DTO let me run the project and see that in action. We go to our post here perfect. Now this is different, we only need a few properties here. Let me change those and we execute. We take a look at the response. Perfect updated is not present. And that looks good. Now created is null you can change that if you want but I will skip that for now. Basically, our details are functional. And we are not exposing our entity, which is coupon that is great news. But having all this conversion is super ugly. I would love if someone would already do that for me. And the answer for that in next video. Mapping all of the objects manually is super painful. Thankfully there is auto mapper so far that we will have to install the new kit package. Let me go there. In the Browse tab, we will search for auto mapper we will have to install the default auto mapper package, then we want to inject auto mapper with dependency injection. So we will install auto mapper dot extensions dot Microsoft dot dependency injection perfect both of them are installed. Now how can we define the mapping auto mapper is smart. If the property names are seen here, it automatically maps them but we need to tell auto mapper that hey, you should be mapping coupon to coupon create DTO or coupon DTO to coupon that is something that we have to tell Automapper let me add a class file And we will write that inside that class file. I will call that as mapping config. Now if you want that configuration, you can do that in program.cs, when we register that to the container, but rather than keeping everything clustered in program.cs, I like to separate it out. Now that mapping is present inside the profile that is inside auto mapper. Once we add that here on the class file, in the constructor, we can call the default methods, that is create map that create map is inside the profile. And there we have to tell the source and destination, we want to map our coupon at a USING statement. And we want to map that to coupons create TTL. Now, that will only map coupon to coupon create DTO. But what if you want to map coupon create DTL two coupons, that is simple, we just have rewards method. And that will handle both the scenario I will copy this next I also want coupon to coupon DTM. We will not be mapping coupon creativity to Groupon TTL. So that mapping is not needed. While these two mapping liquor. Now we need to inject Automapper to dependency injection. And that we will have to do before we build the application. So right here, I will say builder dot services dot add auto mapper. And then we will explicitly say type of mapping config mapping config has all the profiles for our auto mapper that we need. And with that, it will do all the magic of dependency injection. And we can use that right here in our post endpoint. If you remember, when we have to inject the logger here, we were using our logger. Similarly, we want the eye mapper, let me call that underscore mapper. And we need to add the USING statement for auto mapper that will automatically inject the mapper based on the mapping profile that we have. When we have to convert something we will say coupon is equal to and underscore mapper dot map, we want to map this to a coupon. And here we will say we want to map this coupon create DTO. And this will be the destination. So it will automatically map this coupon create DTO to coupon and assign it right here. One line to replace all the mapping. Pretty simple. Let me go back. And here we will say underscore mapper dot map. What is the destination address coupon DTO. Let's add that. And what is something that we are converting are the source here. That is coupon object. Nothing else is needed. Perfect. That looks good. With that, let me run the project and make sure it still works. We were trying to create something here. And great, that is still functional. And everything is working as expected. If you have worked with the API's with dotnet, you know that where we have all the models, like right here we have the coupon create DTO we can add something like required, and we can add data annotation. Then if we go to program that CVS right here on the request, we can check if the model state is valid, then proceed further. But with minimal API's model state validators are not included by default. Well, at least not for now. It might be in future, but that is not there in the roadmap. And the idea is to keep it minimal. So if you require validation, you can of course add your custom validation. Like right here we have the bad request and so on. But if you want to use something else like fluent API, you can also add that in your API project. In order to add that we will be adding nougat package. So right here we will search for fluent validation. We will be installing the fluent validation dependency injection extension. Perfect, that looks good. And with that we can add validations rather than clustering everything by we'll be adding a new folder here. or call that as validation. And we will be adding individual validation. Now validations might be different when you're creating or when you're updating a coupon. So, that means add a class here, which will be coupons create validation for fluent validations, we will have the base class of abstract validator, we will add the USING statement and there it is on generic. So, we need to define what this class will be validating and that will be cufon Create DTL we can add a validation and constructor here. And with fluent validation, we use Rule four and there we define what is the validation we want. So, first thing we do not want name to be empty, and the percent it must be between one and 100 person, Satish great forward, how can we add that validation inside our endpoint right here? Well, we need to inject the validator right here similar to what we did with AI mapper. So, right here, let me add I validator on coupon create DTO. We will call that as underscore validation. And before we check for the name here, we will say variable validation result is equal to acing and on the underscore validation, we have validate a sync insert there we have to pass the coupon create DTO now, we have an error here because this is an async method and we will have to await but the endpoint that we have here is not a sink. One workaround is to remove a weight and right here we can call the get awaited dot get result and that will work that is completely okay. Let me show that. Once we have the validation result here, we can check if the validation result.we have the is valid. If that is not valid, we will return back an error message. Now error messages are also inside the validation result here. So we can say validation result dot errors, duck, first or default. And we can convert that to a string if there are any errors. So that looks good. Of course, if you want you can customize that rather than returning first or default, you can return all the errors, but again, we are keeping things super simple. For a fact, let me run this and show the error message. When we run that we see a weird error message failure to infer one or more parameters. And in the parameter service we have something called as unknown. Well here it says Did you mean to register unknown parameter as a service that basically means the dependency injection that we added for validation here, we of course forgot to add that to our container. So to add that, we will say filter dot services dot add validator from Assembly containing and here the class that we are in is program class that will register the validator service and we can use that with dependency injection. If we run that, everything works and let me try first here are sent we will make it more than 100 and execute. We scroll down perfect, we see the error message percent must be between one and 100 you enter rebel one zero. So our validation is working. But if we go down here, we are using the get a waiter dot get result. Let me continue and remove that in the next video. We are using the get a waiter dot get result. But what if we do not want that we indeed want to await here and we want to make our endpoint async. Doing that is no big deal right before the bracket here. We can write async here and that will make our endpoint an asynchronous endpoint. So that was a super easy fix there. But now I have one question for you. We are injecting two things here i mapper I validator and then this one we are retrieving from body. If we go up well we have the integer Id even if we don't define anything here. Let's say if we are saying that I logger will be present here. And then we have the integer ID FA fronted you will Notice it works that out and grid that works. So, how is the application determining on what it is getting with dependency injection, what it is getting with parameters, and everything is confusing, because we are not seeing that this ilogger is actually being injected. What happens is the application will first see for all the parameters that hey, is there a dependency injection registered for this logger or I mapper, if it is, then I will be injecting that right here. For the other parameters, like ID, it knows that it is expecting an ID here. But if it is a coupon, create DTO or something else, and it does not find any dependency for that, then it knows that that will be provided as parameter. A does all of those pretty smart mapping automatically. And we do not have to worry about that. So that is one thing that I wanted to point out. With that, let's continue from the next video. Now with the endpoints that we have, like let's say we have this coupon create DTO. Right here, we are returning back a coupon DTO. And then when we have get here, we are returning a coupon per get all we are returning an IEnumerable of coupon. What I want to do is rather than returning a different response based on the type, I want just one single response type. And that will of course have a data. Along with that it will have other properties, like any error message, whether the request was successful, what was the status code, and so on. So that way, all of our endpoint will have a standard response message. So in solution here in our models, let me add a new class. And we'll call that API response. In there, I want few properties. First one will be a Boolean on if everything was good. So that will be a success. Then we want an object, which we will call as a result. And anything that our API or endpoint returns back, like a coupon list, or a single coupon, or the coupon that was created. All of that will be in this result object. Next, I want the status code. So that will be of type HTTP status code. And finally, I want all the error message. So let's have a string. And we can call that as error messages. Perfect, that object looks good here in the constructor, we will check to see error messages is equal to new list of string. Perfect, looks good. So rather than returning anything else here, every time we will be returning the API response. So at the top here, we will have a new API response. And when we are returning, we need to store the result in response dot result is equal to we have the coupon store that coupon last year. And once we retrieve that, we can see the response that is success is true. And response dot status code is equal to HTTP status code dot okay. Let me remove system.net here and add that in a USING statement. Finally, when we have results, that okay, we can return back the response that looks good. This way, we are standardizing what will be the return type that will be API response. Let me copy these four lines. And we have the MapKit. Here, let me work on that. We also need the API response, I should have copied that. And the result here is right here with four star default, we will paste that. And perfect. That looks good for the get individual coupon. Then let me copy this again. While we have the post I will paste it right here. And when we are actually creating we can just set a success to be false. And the status code to be HTTP status code dot path request that we were we have the bad request. We did not have to assign both the flags here. That'll cut the result here. everything that is good will be at the end, we will paste it right there. But when something is not valid, we need to assign the error message. So we can say response.we have the error messages that add, we will be adding the error message right here, cut that pasted, looks good. Again, you can be fancy rather than first or default, you can return all the error message, but you will have to do some conversion where we have resulted that bad request, we will return back the response. Let me copy these two lines, we will have to add that right here. And perfect, looks good. Now, here rather than using fluent validation, sometimes you also need server side validation. That is why I have added the custom error message and returned back the response. We go down here where we have the created at route, we will return just okay here, because we have a standard response. That response will have the coupon DTO. So let me add that here. And the status code here. You can of course, a created if you want. And that looks good. We do not need this return statement, we will comment and let me cut and pasted at the end when we have the other created with that the accepts here looks good. But the producers is API response to a one looks good. Let me make sure everywhere we have that it will be API response. Great. We have modified quite a few things. But now we have streamlined on what will be the response for all the endpoint, it will only have our standard API response that you can see. Let me try to get here. And it's success is true. It returns them status code 200 looks much better. Let me try the post here. We will try an invalid percent. And perfect, we have the Edit message. Everything is much more organized with a single type of API response. Let me try to create and make sure that works. Make this a valid one. And we scroll down perfect is success. We have the result that looks good. With that API response. Let me continue from the next video. Now that we have added the cat endpoint get all and post, I want you to take an assignment and implement the put and to delete endpoints. One thing that you have to be careful is with the port request. If I go back for create, we have a coupon create DTO that we don't have an ID. But when you are updating, you will require the ID that needs to be updated. So for that, you will have to create a new DTO call that coupon update DTO and implement all of those endpoints that are missing. We already added them you just need to implement these two endpoints right here. So good luck with that assignment. And I will show you the solution in the next video. I hope you were able to complete the assignment. First thing we need to create a DTO we will copy and paste that and this will be coupon update DTL. The name here one property that I want to add here is the ID everything else looks good. Perfect. We need to work on my port here. Let me go to the map post and copy what we have pasted right here. Route is the same way we'll change that to be math put here. And we need Automapper validator will be on coupon update DTO and from body we will receive a coupon update DTL Perfect. Now that we have validation like me add that as well. Copy and paste here and we have coupons updated to letter Perfect. Now when we are updating, we can add one more validation that Id cannot be empty, and it has to be greater than zero. Perfect validation looks good. That may go back to where we have the HTTP POST. Let me copy what we have here. And we will update for a fact copy that. Let me add some space here. That way, I can easily read that. I think this is good enough. Delete, leave some space. Perfect. Let's see what we are doing here. We have the API response looks good. We are validating let me call this underscore view for update. Perfect. We are validating the result here. That looks good. Let me scroll down. We have the logic for if coupon already exist, we will have to tweak that when we are updating to make sure we don't get the ID that we are already updating. But I will skip that for now. You can add some more validations here if you want. But I will keep things super simple. After that, in order to update we need to retrieve that coupon. So basically, we will retrieve that coupon using first or default based on the ID that we receive in the coupon underscore you dot DTO. Once rated crave that then we can manually update all the properties in this coupon that we retrieved from the coupon store based on the coupon yield DTO that we receive in parameter, we do not need any of these larger care. Let me use auto mapper using auto mapper, we will map that to be coupon DTO. And we want to convert the coupon from store to coupon de to assign that to the result, status code here will be okay and not created. And perfect. That looks good. We also need to add the accepts here, we can give that a name. So let me copy this. And right here, I will paste that name, we can call that as update coupon. It accepts a coupon update DTO and produces will be 200. Okay, great. Update looks good. Let me run and test that. If we try to get here, we have one and two. Let me try to update do right they're not supposed. But try that I ID if we keep that as zero, we should see our validation. Perfect ID must not be empty. We will keep that as two here. Change the name and percent here to be 12. Let me execute with scroll down for a fact it is successful. Let me try to get out of here. And great. Our update is working as expected. We go back and we will update the Delete. I will copy what I have within the method here. They stayed inside delete, we only receive the ID here you can add a custom validator for delete, but we will keep things simple and I will remove the validations right here. When we are deleting we want to retrieve that. So we will retrieve that using first or default. And here we can just check if coupon is not known. Then we will delete and this will be to one from store. In that case, we will remove the coupon from coupons store. Else we have an error here that we can add the error message invalid ID default successes walls so we can return back the response or five looks good. If everything is good in the if condition here. We can return back the success is true. And status code is okay. If you want you can also return no content. It depends on how you want to implement. But with Delete. Typically we return no content. Perfect. Looks good. With that. Let me try delete in action. We get here we have the default Part One and two. If required to delete the ID three, we should get an error message invalid ID. Let me try to here we get 200. Okay, and execute that. Our store now only has one coupon. So perfect with that, update and delete functionalities are working as expected.
Info
Channel: freeCodeCamp.org
Views: 48,465
Rating: undefined out of 5
Keywords:
Id: lFo3Yy8Ro7w
Channel Id: undefined
Length: 100min 26sec (6026 seconds)
Published: Mon Apr 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.