ASP. NET Core 6 - Minimal API Development | Trevoir Williams | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

ASP. NET Core 6 - Minimal API Development

teacher avatar Trevoir Williams, Jamaican Software Engineer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Introduction

      0:57

    • 2.

      API Overview

      6:40

    • 3.

      Setup Project

      4:18

    • 4.

      Setup CORS Policy

      4:53

    • 5.

      Setup SQLite Database

      11:37

    • 6.

      Explore GET Methods

      9:39

    • 7.

      Explore PUT Method

      9:44

    • 8.

      Explore POST Method

      4:00

    • 9.

      Explore DELETE Method

      4:03

    • 10.

      Test API with Swagger Doc

      4:14

    • 11.

      API Review

      0:55

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

140

Students

--

Projects

About This Class

Learn to build an API using ASP.NET Core and .NET 6.

In this course you will:

Build a .NET Core Minimal API

  • Understand .NET 6
  • Understand API Verbs
  • Understand SQLite and Ef Core
  • Use Dependency Injection
  • Understand Swagger

Meet Your Teacher

Teacher Profile Image

Trevoir Williams

Jamaican Software Engineer

Teacher
Level: Beginner

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Hello and welcome to my course, ASP.net Core minimal API development. I'm your instructor for war Williams and I'm a software engineer and lecturer and I have been doing this for the past 12 years. In this course, we're going to get an understanding of how we develop minimal APIs using dotnet six, we're going to understand whole API verbs work whole sequel, light and Entity Framework Core combined to give us a place to store and retrieve data. We'll also look at dependency injection and whole swagger documents help us to interact with our API. Throw this course are going to be using Visual Studio 2022 and sequelae For dotnet. And Visual Studio 2022 is required to use dotnet six. It is a fully featured and extensible IDE, and it is very powerful and allows us to do so much more for development. So without further ado, let's get started. 2. API Overview: Hey guys, welcome to the start of this new section where we will be working on a RESTful API to complement our mobile app. So we looked at all the basics of Maui already. But now we want to go into building a real app. And generally speaking, mobile apps communicates with APA is which is why a lot of them require Internet access. Now if you're not so familiar with what an API is, I'm going to walk you through some of the basics right now. And if you really want to delve into more of the details that you can check out my other courses where I bring you through the ringer with API design. But for this course are going to keep it simple enough that we can get an API up and running and see how we can consume and interact with this API through our mobile app. Now we're building a RESTful API. And wrist is an acronym for Representational State Transfer. Essentially it's an open standard that allows for any kind of client to be able to interact with some endpoint and access some, what we'll call IT resources. For instance, let's take an application like Facebook. We are facebook on our mobile phone, or if it's on our Internet, our Internet browsers, we have it on various devices and we have apps for Android, for iOS, et cetera. The fact is that each of these apps is not feasible, built from scratch. It's actually just interacting with an API that Facebook has developed and keeps on developing. And that is why when you get up updates, what maybe what they do go stay in something, the API and they have to update the way that up interacts with that API. But essentially, the intelligence rests in the APA. And then because it's an open standard, it doesn't matter if it's an Android device or a Windows device, or your mobile phone, or your mobile watch or your smartwatch rather. All of them can interact with this open standard APIs or web service that generally conforms to the rest architectural style. When we talk about APIs and restful APIs, there are certain concepts that we want to make sure we're comfortable with. One is uniform, which means that there is a standard way to formulate your URLs and meet those calls. It is still less. So you generally don't find that cookies and other files are generated on the device to support the API. Call is made once I call this finished, it, it forgets about it. There's nothing really held on, right? It's cacheable, meaning that sometimes you have inflammation that is always being requested. So instead of going to the database or the data store, every single time, we put a cash there so that the API can respond more quickly with inflammation that is more frequently accessed and generally doesn't change that much. It is layered. So you have different parts and layers to the API to constrain what can be done at different levels. Or resource generally represents bits of data or an object in between the database and the client application. And generally speaking, when you're naming your RESTful API endpoints, you want to be self-descriptive. So if it is an endpoint to deal with personally inflammation, then you want to make sure you say person inflammation. So those are just principles. Next up we have the HTTP methods. Now we have different methods in the forms of get, put, post, delete. Those are the most popular ones that you will see being used. There are other ones. But generally speaking, when we're dealing with a Datastore, we want to carry out for operations. We generally call that crowd operations. We want to create data in the database, wanted to retrieve the data in the database. We want to make changes to it or update it, and we want to remove it or delete it. So see IUD. So get handles the retrieval when you want to view the record or a bunch of records. Putting I GET request, put is the u, which is update. You also have patch, but that is a topic for another time. Put the easier one to implemented, we'll be working with that for our purposes here. But we send PUT requests whenever we want to make an update to the data. We have the post request whenever we want to create data. And then we have the delete requests, which I think is self-explanatory, if not the most self-explanatory, one of them all, then we have the HTTP response. So that was the requests that we just looked at. The response is what the server sends back. So we generally have one XX and XX just means number, numbers like 100, between one hundred, one hundred and ninety-nine. The x-axis represents anything from 00 to 99100. Status codes generally talk about communication on transfer protocols to 100. Generally peaks success in the operation. 300s was that there was a redirection. 400 shows that maybe there was some bad data center or from the client. So the user mid are sent data that the server couldn't process. And so we would say it was bad, a bad request or you requested something that couldn't be found like a 404 error. I'm sure everybody can identify with a fluorophore error. And then we have the 500 error, which means that the server is where the problem was. The data came in, but maybe you didn't call into that database connectivity issue or the server was done, then the API would respond with a 500 response. So those are general response quotes and it's very important to get those rights in good API design. So all of this to see that our API will serve as a point of interaction between our mobile app and some central database. Everything we do on the mobile app, we want it to flow through the API because that's where the real intelligence will be and that is what we are going to start this journey on. So in this section we're starting the API design and we'll walk through the basics, doing enough to get it up and running and understand it once again, if you want more details, you can check out that course ultimate ASP.net Core API development guide. You can check that out for everything you need to know about proper API design from scratch. In this course, we're keeping it simple. So in the next lesson we're going to set up our API project and get the ball rolling. 3. Setup Project: All right guys, welcome back. So let's us jump right into it. We're going to open up our Visual Studio 2022 and we're going to proceed to create a new project, but I want an empty solution. So I prefer to start off with an empty solution. So that are blank solution rather, so that I can give the solution a name and then add the projects afterwards. So we're going to be working on a shopping cart mobile app, right? So shopping cart list, so I'm just going to say shopping cart list. That is the name of the solution. So we can go ahead and create that. Now once we have the solution, I'm going to create a new project. So I'm going to just directly the solution, Add New Project. And then we can add an API projects. I'm just going to just search once again for API. And then I'm going to go with a C-sharp ASP.net Core Web API. And then I'm going to call the shopping cart list dot API. Then we hit Next. And now here are some interesting options for us. And like I said, I want to keep it relatively simply, simple for us. One, we're going to be using dotnet Core six now with Visual Studio 2022 preview, you can go back to five, which at the time of this recording has reached end of life pretty much so you probably don't want to go there. Dotnet Core three-point one still has long-term support, so does dotnet six and dotnet seven is in preview. For stability reasons, I'm going to proceed with dotnet six. And we can put in an authentication type. But for now, let's just choose none because we will do that manually later on. We can configure for HTTPS, we don't need darker. Now, here's where it gets interesting. We can choose to use controllers or we can uncheck, so we can use minimal APIs. Traditionally we would always use controllers, but I think this would be a good time to try and see how the minimal API looks. Especially since this is really a lightweight app, but it might just grow on us anyway. So I'm going to untick that untick use controller so that we can use minimal APIs, leave open APIs support. And then the next option that is rather interesting though, is whether or not we want to use a top-level statements. So with dotnet six, top-level statements would have been like the main function and the main namespace and so on. So certain persons would have said they prefer to see it done in six, introduced minimal style classes where you don't necessarily need to be that explicit at the top. So you can, you can choose which one you want. I'm not going to use the top-level statements because I like them like that. And I'll just hit Create. Alright, now we have our API project created. So if I go to program.cs, notice if you're used to seeing the controllers folder in your API development, you're not going to see it here because we untick the US controllers. If you chose to use controls, no problem, you should be able to follow along fine. But because we're doing minimal APIs, or I chose the minimum API templates. What happens is that we're going to see everything happening right here in that program.cs. So once a program executes, it builds up all of the dependencies it needs. And then it goes straight into executing the code or knowing what coding is execute and then it runs. So the API will sit there and wait for requests and everything is running from our program.cs pretty much. I'm just going to run this to make sure that it is up and it works. And it will launch this browser showing us our Swagger doc. So because we chose open APIs support, we automatically have swagger built into our API. So once we run this, we'll see the documentation. So the more endpoints abilities is more of this document expands automatically. So that's it for us creating. When we come back, we'll set up the course policy. 4. Setup CORS Policy: All right guys, so in this lesson we're setting up our course policy. And I tend to do this as one of the first things. Anytime I build an API, why? Well, the API by design is supposed to be consumed by other clients. Other being clients that may not necessarily be on the same server as the APA. No cars is a general security term for any app that is hosted on the Internet. And generally speaking, this policy would dictate whole different resources are different requests rather, can be facilitated by the app being requested. All of that to see. The course policy allows us to reject requests from certain sources are all sources are a low requests. So when we have the mobile up somewhere else, or 60 million mobile apps all around the world and our APIs on one server somewhere. We'd need to have a course policy to say, well, I don't know, I can't keep track of 60 million requests and 60 million mobile phones. So I'll just allow anybody to talk to me. Of course, we can add other security at another level. But for now, we'll just use the course policy to make sure that we can facilitate requests coming from mobile apps after the fact, right? We'll go up to this is what lines seven in the program.cs. And like I said from the last lesson, I didn't choose to use the top-level statements. So it just gets straight to the point, right? It just starts the code because it already knows it's the program.cs, so it doesn't need to declare int, void, program class, etc, etc, etc. So not void class, you know what I've seen? So let us go into it. So we say builder dots services, dot, add cars. Right there it is. And what we're going to do here is set up some options which will guide the configuration. Alright, so we said Options and then use curly braces. And let me make this a bit bigger. Make sure that we can see give myself a little more realistic. It makes sure that we can all see what's happening clearly. Alright, so build the dots services that add CORS on the web or options. And then inside of our options are going to have options, dot, add, policy. So this is our course policy. We have to give it a name. So I'll just say a low all because I'm not willing to put any restrictions. So yes, it's literally going to be Hello all. And then I'm going to start up another lambda expression. Just see a Lambda. And then this is like a builder functions, so I'll just say a dot and then I can say allow any header. So that means any type of request that comes in, gets pulled, etcetera. Although it began, see any origin. Wherever it is, originating from, it being the requests are low it, and then I can see a low, any method actually allow any method is the HTTP method that's coming into header is different. I apologize, the header is up parts of the request body. And sometimes certain hitters could be militia. So we'll just follow any header, allow, any method, etc. And there we go. So that is the policy that we have set up. No, we need to let the middleware, so this is where we build up our services. But then the middleware starts at the up declaration here. And he noticed that the variable here changes, right? It's, or the object name changes, it's up instead of Builder dots, services or whatever. And so then what we need to do is let the AppBuilder know that it should use cores. So I tend to put this underneath that. So I'm just going to say up use cores. So use the cors middleware and please apply the policy that was created called a low. All right, so watch for typos at that point because that's a magic strings. So you might end up debugging nothing if you feel to spilled these two cart to the right. So that is really it for setting up our course policy. I can stop here because there isn't really any tangible way to validate this at this point. Outside of maybe running the API, trying to host it somewhere and then trying to access it from another machine. So that's really our course policy. I already explained why we need it to do this. So when we come back, we'll continue building our API. 5. Setup SQLite Database: Hi guys, welcome back. In this episode we're going to build out our database. Typically, of course, for an app that is going to be scaled for large usage, you want to use an enterprise grade database like Oracle or Microsoft SQL Server. And then the flagship object relational mapping tool, or the, the library that dotnet Core gives us the interact with the database. The flagship one is Entity Framework Core. Know it has connectors for many other databases, so I'm not telling you that you have to use the database I'm about to use, but I'm keeping it simple enough, but I will explain the general concept to you so you can appreciate why I'm making these decisions. So for this course, I'm just going to use a sequel database which will just sit inside of the folder with the APA. But once again, in an enterprise-grade application, you'd want to connect to some remote server for an enterprise grade database like Microsoft SQL Server. So in order to get Entity Framework into our project, I'm going to right-click the project and then go to NuGet packages. And then we're just going to go to Browse and I'm going to search for Microsoft dot Entity Framework Core, sequel light. Once again, if you want to use a different database, so maybe you already know how to wire it up to SQL Server. Then you just look for Microsoft but Entity Framework Core, and you would see the different ones die for SQL Server, for my SQL, etc. So generally speaking, the name is consistent where you just say Entity Framework, Core, duct, and the database engineer, you prefer. Then you would find the libraries. Someone to download. Entity Framework Core does sequel light, and that will come with a few additional libraries. So let me go ahead and download and install that and accept anything that comes up. For this, I will also need another library, which is Microsoft dot data dot sequel light dot core. So I can go ahead and grab that one. And that allows me to do some other important operations. I'll go ahead and install that. Now let's jump back over to our program.cs and then start wiring this up. So I'm just going to put in some configurations and then walk you through them. So what we're doing here is we're setting up a folder. All right guys, so let's jump back over to our program.cs. And I'm just going to put in some configuration lines and then walk you through what's happening when I'm setting up the database path. So the database path is just going to go to the root folder and create a file called shopping cart dot db. Then the connection string I'm just calling a con for short, is equal to a new SQL lite connection. Of course, as you go along, you will need to include some missing using references. So just include them as you see them. And the data source is going to be equal to the DB path. And then we say build out services at the DB context. And we have shopping cart DB context, which has a red line because it doesn't yet exist, but go ahead and put it in regardless. And then we put in the option that we're using sequel ITE, and that is our connection. Alright, so we can create this file. I'll just Control dots and I'll generate that in a new file. So then we have the shopping cart DB context. Now I'm going to firstly meet this public and then I'm going to make it inherited from DB context. So once you do that, of course putting any missing, missing using reference accordingly. So now that I have this DVI contexts, I want our constructor. And then this constructor is going to initialize our tick in the DB context, DB context options. And those options would take itself as its type. We're just going to call that Options and then we'll pass that down to the base, right? So essentially what we're doing is injecting the options coming in from our program.cs. And these would be the options here, you see light. And they were just passing it down to the base, which is the DB context that we're using. Cql ITE. Alright? No, we really just need one table. So I'm just going to say prop. And then I'm going to create a new data type. I'll just call it a shopping cart. And let's call this shopping carts. Alright, so if we're building a mobile app, think about it. You're building a mobile app to help people compile what they want when they go shopping. That's essentially what we're doing here, right? So later on as the app evolves, we might want to put on like some way to identify which shopping cart record belongs to, which user or which which user has those interests into two. But like I said, I'm keeping it very simple. At this point as we evolve, we can put in more fancy things. And I put this in the wrong place, that should not be in the constructor. I apologize, that should be after the constructor. There we go. So this is the property in the EB context. Within the Framework Core, I'll have to do is put in the properties. And actually this should be DB set of type shopping cart. So wondering why it looks so weird. So DB set of type shopping cart gets it's not shopping cart is a data type that we need. So I'll just create that. And I will just generate that class in a new file. So now we have that shopping cart file. I can just press F 12 with it's selected and it will jump over to its definition. No, what does a shopping cart have? No, most entities, and I would say every entity in your database should always start off with NAD. Alright? We could have item name, item name. Alright, as I'm on this properly, I'm here trying to take shortcuts, but it's like my, my my programming senses are tingling. One, when you're adding something to a shopping cart, you would use probably type in the name of the item. You'd probably typing the quantity that you expect to pick up. And maybe you'd want to set a flag to see if it is selected or not. Have you picked it up or not? So here is a string for the item name. And then we have int for the quantity. Or it could be double for the quantity because you could say 1.5 or something. Oh no, you can choose the appropriate data type, so quantity and a Boolean that says is. So those are our datatypes, right? Know that we have those bowl I was running. So now that I have the basic template for what my shopping cart entry will look like. It says, jump back to the shopping cart DB context. And what I'm going to do is override the method for on model creating. So when you write the word override, it will ask you what would you like to override? And we're overriding a non-model creating, and then it will just generate all of that for us, so we need that first line. Then I went to see a ModelBuilder dot entity, that shopping cart. And then I want to say that has data. So in this case, what I'm doing is I'm going to seed the database with some data so that when we run our API to check, we'll see data in there, right? So has data takes a collection of objects of whatever type you are specifying here. So I would just say new shopping cart and then give this an ID of one is picked up would equal falls. And item name would be, let's see, soap and that's a string. And then the final one would be quantity. And we need three bars of soap, for instance, right? Then it's just going to take a collection pretty much. So we can just comma, separates these objects as many objects as you want. Of course, each one should have a different ID, as id will automatically be seen as a primary key in the database. So let's mix it up a bit. Let's meet that one true. And this would be bred and we should pick up two loaves of bread. And this one can remain falls, and this one should be shampoo. I'm just making this up as I go along as it's not Mariel shopping list. There we go. So we have three items that we want to seed into our database table when our app runs. And we have wired up pretty much everything to have a database at the time, at runtime, right? So what I'm going to do is go to NuGet packages and install one more package, at least for null. And this one would be Entity Framework Core dock tools that will give us access to certain commands that we can run because we need to create the table in the database. We'll go ahead and get the tools, install that. And if you just look, you can check out my Entity Framework Core course if you're not so familiar, not so comfortable with Entity Framework Core. But in a nutshell, this allows us to run these commands where we can add a migration and update it to be switches, what we're going to be focusing on right now. So let's go to Tools and go for NuGet package manager and launched that console. And then I'm going to say add hyphen migration. And then I'm just going to say create database. And then we press Enter, let it think about it for a bit. Then once it has done that, we get our migration file, which I'm not going to go into the details off, but in a nutshell is seeing create table and insert the data. And we had seeded three records in, right? So the next command would be update hyphen database. If the database doesn't exist, it will go ahead and create it and then go ahead and put in all of the records. So at this point our database should exist. You can go ahead and build and run and just test it. But of course we haven't built the end point yet. So when we come back, we'll build the API endpoint that allows us to then query or retrieve these records that we know are in the database. 6. Explore GET Methods: Hi guys, welcome back. So we just set up our database now we want to set up our first endpoints so we can see what's in the database. Because when the database got created at runtime on modal creating, we wanted to see these records in, so at least these records should be in the database and all we want to at least retrieve them and see how the API works. So what we're going to do is follow the template that has been given to us. Yes, it's weather forecasts and yes, the data is static inverter in terms of just being this array. But the principle behind how we're going to read our code is the same. Underneath or weather forecast right above the app dot run. What I'm going to do is write up dots, mop, get. Alright, so what happens is that for all of the methods that you'd want to use, you can see a map and then the method type. So we want to do get, gettier of my PUT, post or delete, etc, right? So as we go through them, you'll see that kind of patterns. So we will see mop get, and then we have to give it the address. So to get the weather forecast, you have to see the URL or the server URL slash logo forecasts. We want to get the shopping cart items. We would say slash in our string, slash shopping cards. Alright? And then what we want to do is do an asynchronous. Then we get pretty much so Async and we need our representation of our database. So I'm going to collapse anything that is not absolutely necessary. So we can see most of what we need to see in one shot, right? We need some representation of our database. So I'm going to have to see async database create an object. I'm just going to call it dB. And then we create a Lambda arrow. And then we can write our code pretty much. Alright. So I'm just going to move this down and end with a semicolon. And then our function code will be in this section of the method, right? So I'm going to say a weird DB. Dots shopping cart, college shopping carts. That's fine. List. So pretty much I'm saying select star from that table. Alright? And pretty much that's what it will do. So let's review this, look at this nice and clean. So if you weren't used to minimal APIs and you are used to controllers, you know what, As you'd have a whole big file for really just this line of code with old method and everything. So this is a nice succinct way to see. When you hit this endpoint, get a copy of the database from our service builder, query and return, whatever. Then that's really all we need to do. Alright, so let us test the toes. I'm just going to go ahead and run. Alright, so now let us test this out. I'm just going to go ahead and run the API project. And immediately you will notice that we have our new endpoints, right? So we have our GET endpoint. We can expand that and we can see it, try it out, and then we can execute. So at this point it should hit the method that goes to the database and retrieves our records. Excellent, alright, so now we know that one or API, yes, it's running to our database has been created and the records are there in three, we are able to retrieve them and interact with our database through our API. So before we leave, I'm just going to implement the other type of getMethod. So I get to retrieves data, right? Typically, you either want all of the data or you want some, some of the data. And the way I determined the sum would be some. So ME SUM. But the way you determine what subset of the data you want would be through some parameter that you provide and then you run a query based on the parameter. All of that to see difficulty in an APA, you have two types of gates. Before any other type of gates, you have the Git, which returns everything. And then you get by some unique identifier which generally should either return one or return nothing if he couldn't be found, right? So all I'm going to do is copy and paste this getter method. I'm going to modify the URL and I'm going to see shopping cart slash and then put in a template using curly braces and say id. So I am expecting that when you call this endpoint, you're going to provide some id value, meaning you want the record with this ID. Now, in this In the delegate header here, I'm going to add a parameter to facilitate the collection of the ID. So I'm just going to say int id, comma shopping cart DB context. We know that this is already provided by the, by the system. So that's not coming in from the user, but we are facilitating the incoming id value from the user here. Then our query is going to look differently. We're not going to see a weird shopping cards. Go to the database and find a sink. And then I'll give it ID. And then I can qualify this a bit. No, because it's either going to find it and return it or we don't want to find it and return it. Or we want to maybe return not phoned. So I can see is shopping cart. So this is my way of seeing is whatever it was retrieved here, a shopping cart object. Alright? And I can do a lambda expression and I'll just break lines so that it's not so confusing. So let's see. I would want to return a result of type, okay, with the data that you have requested, which would be the shopping cart object that was retrieved. And I'm sure, I'm sure if you're doing discourse here familiar with basic C-sharp. So lambda expression, not lambdas or a ternary operation. Oh my, I'm sorry about that. So ternary operation would be a logical operation where you see what is the, what is the logic I'm assessing? Is it true? Do that is it false? Do that. It was found and it is an object of type shopping cart then, okay, we're returning that. Otherwise Buddhist see results start not phoned. And that would give that 404 that we discussed before. Now, another one that I would probably want to do right now while we're here, is what if I wanted to find all the items that have been picked up quickly, right. So the thing is that the arrest APIs yours, you can use it, how you can create it all you want. You just make sure that you follow the standards. So I can create another important here to see picked up. So if they call this endpoint is just supposed to return items that have been picked up. Because remember wherever that flower you see the picked up or not picked up. So if it's picked up, only those should come back here. This is going to show everything. And this one is only going to bring back one item. Alright, so far picked up, what I'll do is say db dot shopping carts dot where. And then we put in our Lambda expression and our condition where he is picked up. Alright? And because it's Boolean, I can just leave it like that. And then I just Piracy told to list, which is our executing statement for or if course statement. And that's it. And pretty much we just created three gets endpoints in a manner of minutes, in a matter of minutes. So once you get to everything, wants to get only picked up items. I don't want to get something specifically by Adi, so let me just run this quickly so we can assess or work. Alright, so we have swagger, we already tested gets also on bother with that one. We know that we have at least one item that picked up was true someone to try it out and execute. And I shouldn't get back everything instead, I only get the one item that is picked up, his true Excellent. And then if I want one by ID, I can see try it all done. I provide only the ID of one. The record I get Buck has ID of one, right? If I have provided ID of ten, knowing that I don't know what I asked for ten that I'm getting that for all four response not found. So that's all responses work, right? Notice that when he was successful, we got back a 200 chord. Alright, so that's the O key response to 100 is okay. So when you want to be specific, you can see results that okay. If you just as long as you return something, it will automatically be on. Okay? So that's really it for us creating or get endpoints. 7. Explore PUT Method: All right guys, So we're moving on in our adventure and we're going to go on to the put method, right? So what we have so far would be getting methods we can retrieve, but what if we need it to edit? Maybe I made a mistake when I created the item, something like that, right? So I need to put in PUT method. So the put pretty much takes the new data and then tells the database replaced the old data with this new data. That's essentially all that happens in outputs. So to get our endpoint up, I'm just going to say up dot map ports. And like I said, you will have updated map. And then the method that you want pretty much afterwards right? Now we'll put in our string pattern or our URL. So typically the port looks just like they get in terms of what that template looks like. So we're getting that same shopping cart slash id, right? And then we see is sink and int id. Then we're going to take an object of the type that we're updating. So in other words, we're going to be updating a shopping cart item. So that means if you are sending me a record to update in my database, then obviously you need to send me the record that you want to replace. That record would that ID, what is the data that you want to replace? Essentially, that's all that is. So I have to put in a parameter of type shopping cart, shopping cart. So remember, id is coming in through the template, but the port to request generally would send the data not in the parameter is like what it would be part of the request, the body. So we will see that in a few int id, shopping cart, shopping carts. And of course we need some representation of our DB context. And this is just one big delegate. And then we semicolon that parenthesis right. Now, what do I want to do? First thing is I want to make sure that whatever you're trying to update actually exists. If it doesn't exist, then I'll just really I can't find a record that you're trying to update. So I'm going to do something like what I did here. I went to see a weight, the find method, but before that I have to assign it somewhere. So var lets us see record is equal to look into shopping carts and find the record with that ID, right? And actually, let me backtrack a bit sooner, remove this line. What happens is that we're going to have multiple things doing. So unlike the other ones where there were one-liners, we're going to have a number of things doing so our delegate really can't just allow us to put in multiple lines. So I have to put in curly braces instead of this delegate body. And I'll just close that up. And then inside of these curly braces, I can now put in the various lines of code that I want. So here I can see var record is equal to db dot shopping carts that find async. And then I can end up with the semicolon. Alright? So it's a different style of coding. It's a bit more functional than procedural, like you'd probably be used to both. It's just a matter of practice making permanent. So I wanted to see if a record and generally I like to check for the negative first. So if the record is null and you can check for null by seeing equivalent to null or you can actually see is null. That one would probably read a bit better. If it is null, then I'm just going to return results, dots not found. I couldn't find the record that you said you're trying to open it? No. If it gets beyond that part, then we're going to want to do this update. So I went off to see a record dots and then I'm going to have to pee and stick in legal through each method sorry, each property that came in and not be at it. So record here is what's in the database. Shopping cart here represents the incoming shopping cart data, the payload, the request body with the new data. I don't know if you change the name. I don't know what to change. So to be on the safe side after update everything. So if you're used to SQL and update statements in SQL, you know that you have to change every single thing inside an SQL statement just to be sure, right? So it's picked up, is picked up. What else did we have? We have we had quantity. I don't think we have anything that's global. Can't update Id. Alright, we would want to update the record ID. So after we've made all of those changes, what we would want to do is I'll wait, db dot save changes a sink, then we can return. So whenever we do an HTTP request that doesn't necessarily have anything to return, what we see is no content. So it's Solon's bud. I'm not going to return. Okay, but after update operation, I don't really need to give you back the data you just give me because you already have it. So I would say no content, which pretty much means that I have nothing to return. But this is a tool for, there we go. So it basically says, I have nothing to return to you, but your operation was good. Everything is good to go at that point, right? So let us test out our operation. So I'm just going to run without debugging. And swagger is on the ball with the color-coding, so it gets in blue and then we have are putting orange. I can try it out. No one. I will see you in the ID goes in the parameter. I was also seeing that the rest of the data goes in the request body. So here's where I say I want to update record with the ID1. And then what is the data I want to send over? So these are risky things. And in my, in my full end-to-end API course, I do point out the dangers of having certain fields exposed in life PUT and post endpoints. You can go through that course. But once again, I'm keeping it simple here, right? But typically you would want to take that ID value or you can write the code like we did to not a colon for the id value being imprisoned. So let's say I change these values, right? So record with the ID1, lets us look at it. No. So if I go to the get, try it out and say Show me record with the ID1. It is going to show me ID1 item soap. So quantity three big top is false. I'm not going to change anything in this request body. This request body represents the same fields and corresponding values that would expect for our shopping cart entry. So if I press Execute, what will happen is that to all four it was successful. And if I go back and retrieve that record with ID1, I'm just going to execute this again. Now we're going to see it looking just like what we just sent up as a request body. So if I want to change this to hum and pick up ten homes, right? Executes. All it does is take everything here. And the idea is that it's just going to replace what's in the database. There we go. Alright, so a few things about what Entity Framework did. One, when we retrieve our records, we actually retrieve it. And there's this feature called trucking that is enabled in a retrieve it like this with trucking, any changes that you make to any of the properties are the values. You can just call Save Changes. And it will automatically know that this was changed because he was tracking the values. So once this line runs, it knows that this record is no quote unquote dirty. So when you see if GnG is look at this record and execute the changes that were made, pretty much that's what happens, right? There are other ways because you can retrieve data with no tracking. So what happens is that when you have hundreds of records you probably don't want to tracking because it can cause performance issues. So you would see persons put on as more tracking their queries. But that is usually more for applications that reach that maintain state. So far an API there is no really, There's not really any state that is retrieved. And that's just a teachable moment. I'm just helping you to understand what tracking is and why this was able to work just like that without us calling db dot update. Alright. So that is pretty much it for us putting together the output. So you can think of all the outputs that you may want to setup. But for no, that one is good enough. 8. Explore POST Method: Our guy. So let us look at creating our post method. So just to do this simply and quickly, I'm just going to copy the puts method and paste it again. And we're going to see a mop post, post. This endpoint is not willing to have any parameter on it. So it's just going to be slash shopping cart. And then we are going to take this spirometer and we're only waiting for the payload in the request body, right? So that shopping cart object is what we expect to get two Editor database in terms of the code, we don't have to do any checks. All we need to do is add this shopping cart item to the database. I'm just going to say db dot shopping cart. Or I could actually just say db dot odd. And then we just give it that shopping cart object. And then we save changes. Then what we're going to return would be a Created response. So created would have a tool one, right? Tool one is the status code. So created. You could also say something more like created out to route. So you can give me the root name and some other fancy stuff. But I'll just keep it simple, created. And then we're just going to give it back some data. So it knows that it's created at slash shopping cart. So the response will have the endpoint slash and then the ID. So basically what we're seeing is if you go to slash shopping carts with the shopping cart dot ID, then you can find that method, find that data, sorry. Then we return the actual object. So essentially created and we're telling it the string where it can go to see the created data. And then that is the actual data payload alongside the route that you could go to. And that's essentially it. So let us test this old. So color-coding is that it once again, we have our post method here. Try it. Oh, and I shouldn't be providing an idea when I'm creating, but we already discussed that, that we're just keeping things simple here for now. Let us try another item. This time. I want cereal, and I want two boxes of cereal. And it hasn't been picked up as yet. So when we execute this, that represents our objects that were then sending to the database and C gets created, it gets the ID for and everything is there. So if I do a get all and execute, then I will see 123 and our newly created item, item four. And that's really it for all post method. So once again, we waited for the payload, which then got what will cause de-serialized into this object. And then we added it to the database and then we save changes. So what you would see with Entity Framework Core is that you could actually say db dot add, and add takes some type. It doesn't really know what type might be attempted. But as long as it is off the entity or as long as it can find it in the DB context and you won't get any problems. You would also see db dot and then the specific table and then that ad, right? So I'm just showing you that you could do either one really db dot add shopping cart. And then it knows is just save the changes and it will find the appropriate table to put in the data. And we've seen that that works. So that's it for our post method. 9. Explore DELETE Method: We're back and this time we're going to be looking at the delete method. So we're going to do map delete. Once again, I'm going to take our PUT and then we're just going to retrofitted to be Delete. Alright? So I'm sure you know what it is, but I know it doesn't really matter the order that you put the methods in. It's not went off faked which one gets executed first sic on our third because it's not matter It's not a matter of the chronological order or the order of the method is just which one is requested at which 0.1 thing I should point out is that you should never have two of the same methods with the same endpoint. So let's go back to the good. We have multiple gets, but notice that each one has a different endpoint address, right? So if I had to get methods with the same slash shopping carts, that would cause a problem. But because I've mapped get an Nmap posts, where is it to get it right? My post. And both of them how slash shopping cart, it doesn't cause a crash because one is get on, one is post. So if I forgot to change this and add the two Map puts with the same end point value. It would just cause a problem. Let's actually look at that. It's good to see these errors so that we know what we're diagnosing when we're faced with these challenges. When you do that and solve your loads, it will just tell you hate fail to load is not giving any more data than that. If you get something like this, go back and check and make sure that you're not making that mistake. So a simple fix here is to say map, delete. And it's going to have to retain the same endpoint because we do want shopping guide. I will do need the ID of what we are going to delete, what we don't need, however, is the data that we are going to delete because we can always use the ID to find the record. So here we get the record. If it is not found, we return not found. And then what I'm going to do is just say db dot. It would be db dot remove. There we go. Sometimes I forget these things. So db dot remove and we would remove the record that we found with that ID. We save changes, so I just press Save. And what happens is that there's a feature in Visual Studio 2022 called Hot Reload. So that's that fireball here. So you can actually enable that when you save it does a Hot Reload automatically. It might prompt you like it's prompting me. But you can always just tap hot reload. Then if he can't just reload it, you can just say rebuild and apply changes. And it will do what it needs to do in the background while you are still running without debugging. And when you're running without debugging, you would have this console window open. So sometimes you might try something, I'm just not working properly. Just check for the console window. You might need to close it and then start over. Either way, Hot Reload allows us to just reload our Swagger doc. I know we're seeing or delete endpoint properly. Then if I try it out and then try to delete a record with the ID for which is the one we just created. And we execute that. We see, we're returning that all content. So delete is another end point that you can return no content for, right? It's perfectly fine. The console window, while we're in development mode, you would see those queries being spit out on this in the console. And that could be useful for you to see what gets generated when you run these EF Core commands right foot, although we don't necessarily need to focus on that. And at this point, we have our crowd API up and running. Now when we come back, we'll just clean up our code and make this look a bit more presentable. 10. Test API with Swagger Doc: Alright, so let's get back on it and let us test this out. So I'm just going to run without debugging those a bit more quickly. And we're just going to use swagger tool to test this API. And now an alternative to Swagger would have been like postman or something similar to that. But saga is capable, so we'll just use it right now. So when we expand our get, that implies that we'll be getting back up. Collection will see the sample, the sample object of what we'll be getting back. And notice the square braces, the depicts that it will be an array of objects. Let us take, try it out and execute which point it actually goes on queries the database, and there are all of the sample cars that we would have entered right? Now if I tried to get by ID, let me try that one. So try it all. It says give me the idea, I'll give it ten. And we get back the 200 response with the car with the ID ten. I try it with a 100. I don't have a 100 cars. So this time I get bought that for all four because it couldn't find that car. Bad idea, right? You can pay attention to lead the response URLs. Namely the, this is what we call the base URL because that's the server. And then this would be the path, and then that will be our id value going over, right? So it's good to pay attention to these things because when we're writing code to interact with the API, we have to mimic these kinds of URLs so that verifies that all gets by ID works. Let's try the Pulitzer. If I tried to modify car with ID1, Let's make it into a string, string, string, string, string. So let me first retrieve the car with the ID1 so we can see what it looked like. So that is the car with the ID one and we take our quick copy of it. It's a Honda Fit, Vinny's ABC. Now, when I run this, I notice I would have to put in all the details and tend to update width. So if I leave the defaults and click Execute, it's going to tell me no content, which means it was successful. If I attempt to retrieve this car again, then I'm going to see that it is not working. Let's set the cord. And my bud. This is, this is my silly mistakes. So actually mixed up the assignments I should've been assigning. Record the value is coming in through car. So I apologize for that. Makes up I have on my hot reload on Save, so I should be able to just go back and try again. So that's executes. We're seeing one Honda Fit and everything. And then when I tried to execute here, I get the tool for. So no, I'm seeing, there we go. So now we're seeing everything changed to a string. My silly mistake guys. So that works. And that's why testing is important. Alright, so let me just revert to my original payload and then execute again. And then we can verify that we now see the original data, right, looking good. Then the final one is the delete. So which one would I want to delete? Let us still the I I'm not I don't want to see what kind of car I'm not fond of. What I'm going to delete. The one that I'm least fond of in this list would be the car with the ID four. It'll be too small for my taste. So there we get the tool for that suggests that it was completed successfully. So if I go back and execute, there is no longer a car with the IED four. Just like that, our code works. 11. API Review: All right guys, So the last listen left us with our working API that does basic crud operations. What we don't want is access code. We don't want the forecast quotes. I went to remove that. I'm also going to remove Record at the bottom. And right now, all we have is the code that we know we absolutely need. Know there are different ways that you can organize your minimal API because you could create methods that you obstruct the code to. You could put it in a different class and then call it as a middleware. There are number of ways to do that. I'm really not going to get into all of those ways, right? No. But at least at the end of this exercise, you will know how to create API using the minimal coding style that can do crowd against the database.