Create a Web API with Azure Functions, Azure Cosmos DB and Blazor

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys in this section we're going to get down to some fun stuff so we've been looking at a lot of theory a lot of concepts and you know just getting to understand the inner workings of azure functions in this section however we're going to put all of what we've learned to the test and we'll be building out a rest api so we'll just be using functions building out endpoints if you are not familiar with rest apis you can check on my other courses on rest api development where we actually go through how to build them using a whole api development project template from visual studio but here we're going to be using azure functions so in this video let's just get started we're going to be using visual studio for this one let's just find the azir functions once again if you don't have it to the left you can always search and if you don't have it at all you'll have to go and get the installer and installed as your workload so let's get as your functions and this one i'm going to call i'm going to call it shopping cart list so i think that's a simple enough example we have items that go into shopping cart and we tick them off when we have them right so we can just go ahead and create that and for now i'm going to do an empty template so for the storage emulator yes we want to use the storage emulator we already went how that works and just for context um at this point the azir's traditional as your storage emulator may not necessarily work properly and i would have mentioned that you would have to use azure right so to make sure after you have installed it that it's running you can always just run that command as you're right and then you'll see it's starting up all of the services right so you if you encounter any difficulty connecting to or you're trying to use these emulated services and instead you can't connect just run that command as you're right all right and i'll just have that running in the background so for now let me go ahead and create this empty template and when we come back we're going to get started with creating our functions and looking at the concept of how we're going to lay it out in terms of building out a wrist api like structure all right so let's get this started i'm going to add a function so new azure function and since we're dealing with an api like structure then all of my functions need to be http triggered right so i'm going to call this shopping cart function or shopping cart api let's call it that and add and then i'm going to go with the http trigger i'm going to make it anonymous at least for now and click add all right so now we have our function i'm not going to start modifying it just yet instead i'm going to go ahead and put in some other things so i'm going to add a new folder i'm going to call it models so the thing with api development is that you typically want to have models or details that govern what data you expose interact with for each request so i'm going to have a shopping cart model first of all and i'm going to make this well it's internal so internal means that it can be used by anything inside of the same project so i can leave it as internal for now and i'm going to add some properties so i just went ahead and did all three classes and you can just look at them and replicate them accordingly so we have the shopping cart item or shopping cart in general or actually this should be a shopping cart item all right so let me just update the name of the file accordingly let me just do that cool so shopping cart item has an id which i'm just going to use as a string guide i have a date created and then i have the item name and then i have is it collected or not you know like on a shopping list you strike off the item once you've put it in the cart so that's pretty much what that is um signifying right and then we have one for the create so of course for the create i'm not going to expose everything i don't want that the user to be in charge of the id or the created and booleans default to files so without me specifying that or needing that from the user i'm assuming that it's not yet collected so all we need is the name of the item for the update you may be changing the name of the item you might also just be changing collected or i could just you know allow them to just say yes it's collected or not so i think i'm going to keep it that simple and just work with that later on when we're connecting to the database then we'll have to create some more models but for now this is all that we need so in a rest api these would be what you call dtos or data transfer objects once again if those terms are you're not familiar with them you can always check out my course on api development however let's jump back over to our function and then what we're going to do here is actually establish our roots so the thing with functions is that by default we're getting this class yes and then we're getting one function with run right in this case it's saying it can do get it can do post we don't really need anything to do both because in a rest api setting it should be very strict one for posting one for get or at least at the very basic level but each function should be in charge of one operation at a time so since we're mimicking that rest api structure and standard we're going to have to modify this so what i can do is rename the function so if this is supposed to get shopping cart items i can call this get shopping cart items right so that's a function name however for the root i want to specify a value because i don't want that when you call the function you have to say slash api slash this function name and then that function name once again rest api um standards would have you call basically one api one structure but based on your verb and potential um parameters or values being passed over then it would know which function exactly you are referring to so we're going to rename this root so that it looks a little bit more like what a rest api would look like so i'm going to call it shopping cart item so you're expected because it's already going to be the url api slash and then the function name but when i specify this as a root then it will know that from the http request anything going to that route after the slash api will be going to this function right next thing is that i don't want this function to post i want it to retrieve so i'm going to remove that post and just to make sure everything looks good i'm also going to rename the function itself to reflect what that function name is so that everything looks kind of uniform right um for now i'm going to remove all of this uh yeah i can just remove all of this from the function because what we're going to be doing um doesn't require all of that per se right so that is the one to get now once again we're doing a rest api so that means i need one to create so i'm just going to copy all of that and i'm going to call this one create shopping cart items i'm going to give the method that name and this one is going to be the post because it's not getting this time it's creating and anytime you create you should use post and then it has the same route so it's going to be a post request to that api or that http root this one is a get requested that http root right and then we can do the same thing for put and delete so put would be for updating and deleting well that thing that's self-explanatory right so put shopping cart items or item and let me just make sure that my methods are really reflective of what the operation is going to be so delete shopping cart item delete shopping cart item this one is a put request and this one is a delete request all right so once again we're just mapping out roots they may change as we go along we might see something that we want to change of course we're going to be changing the parameters when we're focusing on each one but for i'm just mapping them out so we get the big picture um there is another type of get because maybe we want a specific one so if we wanted a specific shopping cart item then it would be get shopping cart item not items this would also be a get button for the root would be shopping cart item slash and then we're going to use a binding parameter to let you know that it should expect something called id afterwards so i've get all the items all right we have get by id pretty much your shopping cart item if you want to qualify just so you're very clear and you know that that is what it's for but all it is is just that slash the id we have the create which is just a post and then we have the put and we have delete now that we have a good idea of the big picture when we come back we can start working on them one by one all right so we're back and we're going to start off with the create shopping cart item so the first let's update our log message and it's just going to say creating shopping cart item right now in the request we do have the data coming we've already seen that this request could have looked in the body or in the url and since it's a post we're expecting the data to come in the body so i'm going to start off with a variable called the string request data where we're going to await a new instance of the stream reader and the stream reader is going to go into our http request parameter rec dot body and then we want to to read or read to end rather async all right now that we have read it this is going to return that json body pretty much we want to serialize it into our create shopping cart item object right so i'm going to save our item is equal to and i'll use json convert now json convert comes from our newtonsoft library and that was already included here it's basically a requirement for http triggered functions we've seen it we've used it before but my point is that it's like any other package is just a new get package so if you already know how to get packages in you can just go to manage nuget package and add it right here without any qualms right so we want jsonconvert.deserialize object and we want to deserialize into our create shopping cart item object and then we give it the request data which we know is json in nature then after we've done all of that we would want to add it to some some database right pretty much our database is going to be of type shopping cart item because we want the defaults right so before i do all of that let me just create a new instance bar okay let me change this from item to data right and then i want to save our item here is equal to a new instance of the shopping cart item shopping cart item and this new shopping cart item is just going to take that item name which is coming in from data data.item name right so once we have that object that we would want to save we want to save it to a database so i am not yet ready to start up the whole connected database stuff so what i'm going to do is just use create a static list so i'm calling it shopping cart items is equal to a new instance so down here i'll just say shopping cart items dot add our new item now let us pause for a minute and reflect on the relevance of using this list what the pros and cons are obviously in a real setting wouldn't be using a list like this would be using a database however i'm not ready for the database just yet so we're going to be using the list now the thing with a function app is that while it is running it is going to be storing any data any variables during the runtime so while we're testing this is perfect because we can call all the different methods and would be interacting with the same list in a production setting remember that functions are able to scale so that means that if you were to deploy this while it may work for some scenarios while your function app is running because remember that on some plans it will actually be turned off until you have to spool it up again so that's one danger but two let us assume that doesn't happen it can scale to have multiple instances so then you would end up with multiple instances of the list which is another danger so of course that's why i would want one database but for now we'll just use our list so after we add it to the list we can then return a new um okay object results and i'm just going to pass in the new item not the whole list but just the item that was now created so that's really it all of our errors for our create shopping cart item are gone and that is step one so when we come back we'll be going into our gets so we'll just do both gets in one go right gets all versus get by id all right guys so we're back and in this lesson we're going to be focusing on our get methods so the first get method which is to get all items that one is fairly straightforward so my message is going to say get getting all shopping cart items and then all we're really going to have to do is return so at this point would really go and query the database and say give me all right in this case we don't really have a database we only have this list so all i'm going to do is okay return on ok object result with the list so that's the list of the shopping cart items and once you want all you get all so that's pretty much it i have an error here ah sorry i missed off my new return new okay object result there we go so that's really it now for the get by id it's a bit it takes a bit more finesse right so yes we have the same route we know that this one is expecting an id value coming in so that id value usually comes in as a parameter so in an http request it could have come in as the http parameter um i'm going to add a new parameter here as a value so string id and then i'll just use the comma so string id is going to represent the id value that should be passed in when this function call is made i'm actually going to put this as the last thing so i'm going to put it after the i logger the string id all right so once this method is called we're expecting this id now once we have that id and i'm just going to rewrite the logger message getting shopping cart item with id and then i'm just going to encapsulate the id value that's being passed in right sorry interpolate not encapsulate so now that i have that i'm going to say var shopping cart item is equal to i'm going to go to my shopping cart items list and then i'm going to say that we could use find but i'm going to stick to what i am more comfortable with first or default because i'm going to do first or default if it doesn't find it it will return with a null right so first our default and then control dots to use system.link and then we put in our lambda expression so q dot id of the shopping cart shopping cart item will be equal to the id value that is passed in and then once we have done that i'm going to now check i see visual studio is helping me along if the shopping cart item is null meaning well obviously it didn't return anything then we would have to return a new not phoned object result so that's a 404 right otherwise otherwise okay so here's the difference between because you might notice that you have object result versus results right so you have okay result different from okay object result the difference is that when you return the object results you need to put in data when you're not returning data so in this case i have no data to return right it's expecting some value so i have to say not found result so they really amount to the same thing it's really saying 404 but just which one to use when appropriate right so we are going to return a not found result otherwise we're going to return a new okay object result with that particular shopping cart item in hand so that the caller would have gotten the data so let's review quickly to get multiple items get shopping cart items all i'm doing is running a query quote unquote running a query against the data store and returning all right now the data store is a list so i'm just returning what is in that list when we want by id i have to specify that i want the parameter id to be present they're already both get we already know the roots but this one is slash id hence my need for the id and then once i have that id i try and run the query to find that one object in the data store if i don't find it i return not found result otherwise i return the okay object results so that's really it for the get methods of our rest api all right guys so let us jump over to our put so we're looking at updating our shopping cart item now we have to make some more changes because when we want to update we would have to pass in an id as well as the data to be updated right so we're going to have to do what we did up here which is include our id id parameter there we go and we have to update our root because we also need that slash id on the end of the update root all right then we can change out our log message to say updating shopping cart item with id pass that in now we have to do kind of a hybrid operation the first thing that we have to find the data so we can repeat what we did in the get so i'll just go ahead and say get me the shopping cart item that has the id that was passing as a parameter if we didn't find it then return not phone all right next we are going to have to repeat something like what we did with the create so i'm going to have to parse through the incoming data and this would be parsing into the update shopping cart item and then in a bigger operation we could use something like automapper to map between the incoming data and the shopping cart item to do the updates but this is a very simple operation so what i'm going to do is simply update the shopping cart item dot uh collected flag and let it be equal to the data.collected flag so you're updating it it must mean that you're changing the boolean from true to false or vice versa that's all we're really going to be updating then at the end of all of that we're just going to return our okay object result and i will just return the updated shopping cart item as the object right so that's really all there is to the update so let's go through it again because i kind of took code from different pieces so let me just explain what we're doing one we're finding the shopping cart item with the matching id that was passed in via the parameter then we're going to say if nothing was found we return a 404 otherwise it will continue to say get me the data that came in in the request because with a put the data would be in the body it's very similar to how it would be in the body for the post so get me the data from the body parse it out into the corresponding model for updating and then we're going to manually update so i'm doing it manually in a bigger operation like i said you'll probably use automapper or some other third-party library or write a converter to have that done for no two very simple operations or a very simple operation so we'll just do that and then we return the updated object as part of the return result so that's really it for setting up the put when we come back we will do our final one which is the delete all right so let's get started with the delete operation so i think we've been doing this long enough if you want to hit pause and try and do it yourself then i would encourage that otherwise we can just walk through it already wrote the code so we had set up the delete shopping cart item method from before what we didn't do was threshold the root so the root once again will require an id value there and we have the matching parameter string id updated the log message and once again we try to find it if it is not there then we say not found result however if we continue we say remove it from the shopping cart list and then return an okay results note not okay object result but okay result since there is no data to return and that's really it for the delete method right so with that we if we just do ctrl shift and b we can build and make sure that we have no errors anywhere in our code and we can see that we have a successful build zero errors and we can continue so now that we have fleshed out all four of our operations when we come back we'll just go through some testing we'll use postman to call the different endpoints and make sure that it is functioning or that our functions are functioning the way we expect all right so it's testing time we've done all the hard work let us put it to the test so you can just click the start button here in visual studio to start it up or if you're using visual studio code but i know you know how to run that and then in our that console.com the execution we get a list of all the functions so we see all of them by name thanks to the function name attribute that we added but we also noticed that each one has a root so yes the root would have been you know based on the name that was provided by default however we overrode that and we put in our own roots and there you can see how you can call each method according to the root so if we test with postman or any other http testing tool and i say okay call the get all methods notice to get all shopping cart items i would just call that url so you can actually just highlight it and then copy and paste it into postman click execute and then you'll see here that you would get that status 200 okay but nothing because we haven't put any data in of course you'd also see the log get updated so getting all shopping cart items and then it was executed at that point in time so let's just try and create a new shopping cart item so i will just change this method to post and then in the body i have to make sure that i send over some json so change that to raw and then change that to json and what did we specify in order to create we are only accepting the item name right so i'm going to say item name then colon and remember to put in a quotation marks and then colon and then this would be test from postman so when i click send let's see then you would see it replies with the newly created id that timestamp the item name and if it's collected that's false so if i retry my original get i'll just open a new tab use the same url but we're using a get and i send then i'm seeing that i'm getting back that one item from the list right if i try my other get um this one requires the id so i'm going to say slash and then pass in that id value copy paste it there then i should only get back one object there we go so i think that this is working well let me try the update so i'm just creating tabs accordingly so once again we have this url paste it there or actually i should have just used this url because for the updates we do need that id value i'm going to do a put and then inside of the raw requestbodyraw.js i'm going to say that collected is now true right so colon and the value true let me send and then you see here it returns the updated object letting you know that it is now true so if i go back to the get get all and send again then i'm getting back updated so like i said if you call these functions within the same session i'm going to call it a session so we're executing right now um we're calling one after the other one after the other it's updating the same list each time so that is why you're getting those results of course if we stop and restart then that list is going to be emptied out so it's the same way that's a function up once it's running if you're using that list then no problem but then once it scales or it's it winds down and then has to wind back up afterwards you just know that you're going to lose that data so you know you have to be careful with that but later on once again we're going to be looking at using persistent storage in the form of azure tables or any other storage medium that you prefer so that is really it so the last one that i'm going to do is a delete so i'll use this url go over here and this time the method type is a delete we have the id and everything i don't need a subject body response 200 okay no content if i go back and try to run a query nothing comes back if i recreate then i get a new id and then if i try to look in there again i see everything so that is literally all there is quote unquote all there is to arrest api the more difficult it becomes is based based on your business needs but at the end of the day this is how easy it is to create a whole rest api using just as your functions now a fundamental part of any apis development is how it interacts with client apps a client app can be a mobile app it can be a web app etc in this case i made a simple blazer app where road code interacts with the different endpoints from our azure functions api so while running it i have we know that we have all the roots already and all i did was retrofit the fetch data page from the typical blazer app template and what it does is test from blazer when i put in an item here and say create it will actually update sometimes what happens is that when you interact with the the console here it will cause it to pause if you just press enter it will continue so you see here it actually made the call create shopping cart item and then it did the retrieval and there's our new shopping cart item right if i say it is from laser one and let me just make sure that the console knows that it should operate normally when i click create it updates and that's now in the list if i click the tick for collected you see here that it will call the put here we go so put so it updated it all right and then if i remove and once again i keep on interacting with it so it pauses but when i click remove it should remove the item let me try that again there we go so let me create a few more and then let me delete them right so each time i click delete you'll see it updating the interface so i'm just going to walk you through the code that i wrote for this it's not really a blazer course i'm not teaching how to build a bazer app i have other courses for that but just within the context i'm going to show you that from the blazer standpoint it doesn't know or cure what the underlying infrastructure of this rest api is it's just going to be doing blazer stuff relative to our api so i created a brand new project and it was just a blazer web assembly app simple ways to do that you just go to the solution right click add new project you look for blazer web assembly app you i'm using dot net six go ahead and create it and then by default you're going to get um some address here base address with environment host that change that out to be the base address of where i know our functions app will be broadcasting from right so we know that that is the port uh we would have done some testing with postman we know that that is our standard api route all right so that is the base address for the http client being used in our blazer app now another thing that i want to point out is that we had to set up cores so cores is cross origin reference okay i'm sorry here's the definition so cross origin resource sharing there we go so that's a protocol or a set of rules that govern how your api interacts with resources that are not on the same server so while we were running the function up and testing with postman it didn't see a problem however when i'm broadcasting or sending a request from an external source like this blazer up when it's executing it's executing on a different port therefore seeing it as a different app altogether then it would actually reject it so this is how we enable cores on an azure functions app so in our local.settings.json file we go to host and we open up a new object block where we set course to be star meaning accept all requests don't have any restrictions right of course when we deploy to azure that will be handled on the azure site but for local settings we have to make sure that is in place so you can go ahead and do that i also would have replicated the models folder so i just redid them down here in the blazer app and instead i updated the namespace with shoppingcartlist.blazer.models as the name of the app is shoppingcartlist.blazer right so you have the models are accessing models there now another thing that i would have done would be to update of course the fetchdata.razer or if you want to make a new page that's up to you but i just did everything on one page and i'm just going to walk you through all of the code that was written so we have the page title we have the h1 and the p tags that's all just you know semantics you can or don't have to do that then i have the edit form up top where i have that input text which i am binding to an object called item create and i'm accepting the item name so here in the edit form the model is item create and on valid submit we're going to call the method handle create so then i have this submit button for my edit form so item create is of type shopping card item and i just have an instance of that there and handle create is going to just say response awaits the http client what is http that is the http client that i'm injecting into my um my component so that would have been already there because of fetch data it's actually a sample of how you can interact with the http client so you don't have to put that there it should be there already but what i'm doing in the handle create is i'm saying http dot post as json async and then post a shopping cart item and actually i just noticed that this is wrong that should be create shopping cart item really doesn't matter in the grand scheme of things but let's just work with it so that should be create shopping cart item so i am posting a json body or json serialization of create shopping cart item and it's going to the the address api slash shopping cart item so this api slash shopping cart item just gets appended to our base url here in the program.cs and then we're sending over the item create object all right then we say if it is a success code okay or no content or whatever it is we've seen we know the different codes represent different things so an okay response is a success code then we just called await um on initialized async which basically just redraws the entire thing so for the uninitialized async we just say items which is an array of shopping cart items is equal to http dot get from json async shopping card item in a form of array and we have the same route there all right um i'm not going to go all out with architecting and best practices in this particular example i'm just showing you a quick win right if you want all of that you can check out my blazer courses so our uninitialization gets all the items and puts them inside of this object which is designed for the items handle create basically just says post whatever data came over as json to this endpoint and then go ahead and update once it was successful now the rest of it would just be me changing out the weather forecast sample code that was there and just using items where it would have said forecast and changing out the table headers according to my new table headers based on the new data and then for each item in items remember items coming from our api call i'm just updating or displaying sorry the different values now for the checkbox section i have an input which is of type checkbox and i just give it a class so it looks kind of nice the value is going to be bound to whatever item that collected is and on change this is an event that means that whenever you change the value of the checkbox i want to call this method checkbox clicked passing the item and passing the value of the event so because it knows it's a checkbox that event is going to have data was it a true or false change etc right so we're passing in that value so when that checkbox clicked method gets called it is going to take that shopping cart item and this could easily just be um and probably really should be the update or the put whatever um object type we had used there but of course it's going to clash here because this is of type um shopping cart items so i'm just showing you that i'm taking the shopping cart item object here and i'm taking the checked value as my as my event args value right i have to make it an object at this point then i formulate my update shopping cart item object and set the value that i know needs to be set and then i'm going to send over put as json async that object type and i'm going to be calling the url and then using interpolation i'm just sticking on item.id so that's why it was important to pass over the item because in doing the update we may need data about the original item like in this case the id so i'm passing over that id and the whole object with the data that represents update and then if it was successful then you redraw right then for the delete we have a simple button uh we give it some bootstrap class and then on click we have similar code event and pass over the item so pass over all the details about the item to be deleted even though we really only need that id so we are just going to say var response http dot delete async not as json because there is no json to be passed over there is no data to parse just delete and the uri would be aps shopping cart item or item dot id and then we redraw so that is why you get that sort of real time look and feel to the ui because i keep on redrawing each time the operation was successful right and that's really it for blazer interacting with the api of course it can get a bit more complicated based on your needs or whatever of course the api could be a bit more complicated but once again we're just looking at quick wins and once you understand these core concepts you can always build on that for your future operations so that's it you can hit pause at the different points and replicate the code i'll just scroll through slowly enough that you can hit pause at the different intervals and you can see all of the code and i would encourage you build more endpoints or more behaviors in your api and build more pages and components interact with said api once again make sure that you update your base address and make sure that you enable the course settings on the api to test them simultaneously you'd want to go to the solution right click go to properties and then you'd want to select multiple startup projects and you can put both to start or both to start without debug whichever one you prefer based on your testing um process right so that's really it for testing using a ui welcome back guys in this lesson we're going to be going through some of the changes needed to start talking to the database so the database that i've selected for this exercise is an azure cosmos db database we already have some experience dealing with that we looked at using it as an input trigger or input binding rather and how we just pass the data in and it will communicate with the cosmos db in this we're going to be taking a slightly different approach to just using input bindings because there are certain operations that we want to do and i think it's it's mixed you know we can write the code three different types of ways if we use the input binding because based on the situation the code is going to look differently or we can be a bit more consistent so i'm going more for consistency in this situation and i'm going to show you guys how you can one set up your function up for dependency injection and to how we use a cosmos db client for that whole injection which can be used all over the place anywhere else in any other function so to get started i want us to go over to nuget just right click your functions project and go to manage nuget packages and get this one microsoft.azure.webjobs.extensions.cosmostdb so this package actually gives you an api for cosmos db as well as table storage but we'll be focusing on cosmos db right now the next thing is to create a startup class now a startup class would be similar to what you see in every net core application so we have a blazer up here in.net six it looks a bit more condensed than what you're probably used to but this is pretty much that startup class that they kind of condense into one file so this basically bootstraps a number of services to be readily um available for dependency injection anywhere in the application once application is running or once you're writing code right so that's what that does so we created our own i'm calling it startup.cs and i'm just going to show you the code and walk you through each line so that we have a full appreciation of what's happening so just right click your function up add a new class call it startup dot cs you might get an error or some feedback that you're creating a function type that already exists that's fine but you can just erase all of that or anything that doesn't match what i have on my screen you just go ahead and correct it accordingly so we have the first annotation assembly colon and we're doing a functions startup and it's going to be type of startup all right and you might have to include some missing references as you go along so you just do that accordingly our namespace is our shopping cart list we know that already and then we have our cons sorry our class startup which is inheriting from functions startup then we have private static read only i configuration route configuration is equal to a new configuration builder where we're setting the base path to be the environment current directory that's the directory of the project we are adding a json file app settings.json true but then of course we have the local settings.json so we know how to access that later on and then we're adding environment variables and then we just build then of course it would give you an error saying you need to implement the abstract class which is functions startup and doing that would generate this method stub for you so it's a public override void configure all that is generated for you but inside of that method what we want to do is say builder dot services and add a singleton so a singleton pretty much means that whatever you're adding here is going to be access one instance is going to be accessible throughout your application so one connection to our cosmos db the same connection to the cosmos db will be used each time we access that this dependency pretty much right so if you want to know more about dependency injection and how that works you can check out my other courses but i'm just going to go through with this now so var connection string is equal to and then it looks in the configuration right so remember configuration compile all of these elements including our settings file so we already have that settings file even though the name is different it will contextually know where to find what so we're seeing configuration get me the cosmos db connection which is what we called it in our local settings file right so we looked at this already i'm using the emulator and i'll show you in a few the database that we've created so just make sure you add that key cosmos db connection and then we add that emulator key accordingly so we're calling that db connection and then we're saying if it is null or empty then through an exception otherwise return a new instance of the cosmos client builder with the connection string dot build so that is our startup class that we have configured once again so that we can inject whatever dependencies we've defined we only defined one which is for the cosmos client now let me jump over to our cosmos db we already have some experience with this this is our emulator so you can go ahead and go to your emulator and create this new one so we have a new database i'm calling shopping cart items and then my collection name is items and for my my key or my partition key i'm using this word category so we're going to be making some changes to the models as we have them but remember that the partition key is like a high speed lookup so it kind of like indexes your records or your documents quote unquote so that it can be found faster so we're adding a new property called category which makes sense right it's a shopping cart item list what is the category is it food is it clothing is it a need is it a want etc right so with that we can better partition the data and speed up the lookup speed up the operations against this whole database so you can go ahead and do that so after you've created the database let us look at the changes to be made to our models so the only change i'm making is really to the shopping cart item and i'm making a change to create so let me go with a shopping cart item first so shopping cart item one of making it inherit from table entity which is courtesy of this new class microsoft.windowsazure.storage.table which comes in our new package all right and so you can let it inherit you don't necessarily have to but the benefit quoting code of letting it inherit is that the class or the model will now actually have access to all of the properties that get attached whenever a document is stored so you'll see a lot of other meta tags you probably noticed them from when we did the blog exercise there are a number of other meta tags that get attached so once it inherits from table entity we'll actually be able to parse them over now i've also added a json property annotation to our id rec property sorry so this json property basically says that yes i know i'm capital i d in c sharp world but in json world please make me a common id the relevance of this is cosmos db is looking for a property with common id so when we set that id value you'll actually get a bunch of errors you can try it yourself i actually had a little field day with it until i remembered that i needed to put this there right so you can actually try after i show you all the code and everything try to do a create and you'll see the errors that you get it will complain that it's missing the id column even though it is there so we just say when you're in json please identify as common id and then cosmos db will be able to see it and say okay i see the id value present of course we're not allowing cosmos db to generate the id we are doing that so that remains the same i've also added another property called category so like i just said category is going to be our partition key and just like with the id we need to let it know that it is a common case category of course this just needs to match how you wrote the partition key right so i'm just going to leave it like that capital c for code but command c for json then inside of the create i'm also putting in that category so when you're creating the item you say the name and the category and of course there are better ways quote unquote to do this you could use enums you could use a select list etc but for now we're just going to keep it simple just so we can understand the exercise at hand for the updates that is actually kind of optional so actually i'm going to take it out and i'll cart the code when we get there so i'm going to remove that so the update doesn't change right so we're just adding category here and for the shopping cart item we're adding that and this json property as well as the json property above the id all right so we're coming along nicely let's jump over to our function now you notice one i have removed all of the static keywords right so public this was public static class i removed that because static classes can't have constructors right and we need the constructor for injection another thing is that uh sorry i just removed that line so if you started typing it you can disregard it i apologize so another thing is that we can't have static methods because we have to modify the code in there and that means we have to use the private fields that are going in right so as soon as i explain what's going on here i'm just showing you the error that you'd get if you left the method as static so no static class and no static methods all right so let us go through line by line and see what is happening here so firstly i'm injecting the cosmos client cosmos client is coming over from our start up so this is returning an instance or the dependency needed for us to access the cosmos client so i'm just going to write a constructor shortcut for constructor ctor tab tab and then you could actually just write in the cosmos client and then using ctrl dot it will offer to initialize and inject the field for you so i'm just showing you keyboard shortcuts so you can write it in quickly so we want the private read on the cosmos client and that gets initialized inside of our constructor and then we have a private container document container and then we're going to say document containers equal to cosmos client dot get container by the name shopping cart items with the collection items if you hover over that you see it asks for the database id and the container id all right so with those two with the document container i can now access the database the items and do all of the operations i need so i was making the point that i find this a bit more consistent to do with a few lines than writing in individual triggers or binding code per method right so what would have happened is that i would have to write cosmos db and then i have to initialize the cosmos db to have the connection string value so i'm going to do that quickly and show you what it would look like and that's it so that's what our annotation would look like as an input binding so when we looked at input bindings previously we did it with a typescript project where we actually modified the function.js json file there's no function.json file that gets generated for us when we're using the c sharp project so we actually put in the bindings and the triggers right here in our function as annotation so would say cosmos db what is the database name what is the collection name and then the connection string which of course would just point to the name in the app settings and then we would call it document client client now based on the situation you might end up using different data types here so for getting all items we would use the client and then the query code would look like this all right so first we would have to find a uri or generator uri for the collection so i'll say uri factory dot create data sorry create document collection uri and then we give it those so here you're seeing that i'm repeating these strings all over the place you'd probably want to think about using like a constant class a constant for the database name a constant for the collection name etc right um so notwithstanding that we would just pass in the database id and the collection and then we would say i document query relative to the data type we're about to query and then client document client dot create document query and then we pass in the uri as document query now these can be extended to have like where clauses they could even say like where and then you know put in some condition by which you want to find the documents right so it could be that you want to find or do like a search that would come in handy for something like a search either way this would return all of the documents and then we'd say while the query has more results we would query through them and then potentially populate a list that we would intend to return so like we had that list up top i've removed that also and i'm just using it here locally right so you would actually just add each item to the list if that was what you were doing so we're not taking that approach i'm just showing you because it's good to know your options right so that i'm going to comment that out and i'm going to comment this out so at least when you look at the source code later you can see that this would have corresponded with that code however because i've injected the client up top i can now go straight and say so first i have my list generated here or declared and then i say var items is equal to document container dot get item query iterator relative to the type shopping cart item this is going to basically go off and just get everything and then we'll say while items has more results we will just go ahead and add the range to our new list all right so var response is equal to items.read next they sing and then we just drop that range into or yeah drop that list into our list and then that's what we return and come to think of it i could probably even cut this line short let me see if this would work and say items dot read next async dot okay so it's a it's an asynchronous of course i would have to await but then if i do that awaits then i would be able to do a to list on what is returned there we go so i probably don't even need all of this anyway two lines all right so you see sometimes you write something and then you realize i could have written it a bit better so i'm going to comment that out for now and then we can come back and test and validate if my refactor works as expected but you see go out get the items and then we get them is in items dot read next async which basically reads or what is in the items we wrap that in a brace or in parentheses so that we can call the tool list on whatever is returned right and that is what we're returning when we try to get all so let's move on now so the get by id so here is where it would kind of be a like for like based on what we did previously where we actually had that binding where we looked for the id and for the partition key which in this case is category so here i've modified the route to say give me id and partition key and then those are the values i'm going to use to run my query right so i could actually have used the same kind of binding that would have used previously inside of this method here and that would actually help us to get back the one the one record that matches this id and partition key so here's an example of what that would look like that binding code so cosmos db we have the same database name collection name and connection string and then i'm going to tell it that the id is bound to the id coming in from the parameter here and the partition key similarly is bound to the partition key coming in here and then that is just going to basically go to cosmos db do the lookup and store the result instead of shopping cart item and then once we have shopping cart item it would be as easy as returning okay object result with the shopping cart item but like i said i prefer the kind of consistency because this uh this binding code is going to look almost entirely different from this binding code and you have to be very careful and i'm not saying it's bad i'm not by any uh means bashing the code i'm saying that it's not my preference right but i am showing you what your options are so i'm going to comment this out so that at least you have it as a point of reference but what i have done here is to say var item is equal to awaits document container read item async so get item query iterator that's how we get our collection this one is when you want one we want a shopping cart item and i give it the id and i give it the partition key which is category of course i likewise extended the parameter listing to include the id and the category and i adjusted the route like i pointed out to have the id slash the category on it so when you're trying to get you should pass in the id of what you're getting as well as the category name so you can do a quick look up right so that is what we do and then the item is actually going to come back with a status code right so it's going to say if the status code is equivalent to http status code dot not phone then we return our not found result right nice and simple otherwise we go ahead and return the ok result or ok object result with item item.resource so you'll see that i wrapped it in a try catch because i was doing something wrong when i wrote this and i needed to see the exception so you can do that if you need to but it's really and truly not necessary so i'm going to remove it just so i can simplify the code and show you exactly what is required all right so that's how you would look up one record from the cosmos db data store now let's review what happens when we do a create all right so what we're doing here really and truly is saying that we want to do the same kind of binding so of course i commented it out but if you look at it it's the same kind of binding except this one would be an outward binding right an output binding so this is an input binding this is an output binding because then it's going to output something to the cosmos db so essentially it is getting the cosmos db collection database we know all of that but then the last parameter here is of type i async collector relative to the data type we know we want to process and then the name of it let me put it in the same line so it looks a bit more uniform right so that is the data type we have to use because we're operating a synchronously if you weren't doing it asynchronously then we would just do an out variable but you can't use old variables inside of an asynchronous method so we have to use the iasync collector relative to the data type and then shopping cart item and then later on in the code after we get the shopping cart item and everything would actually have to do something like this to add it to the collection so i would say await shopping cart items out so i corrected this name that should have been shopping cart items out i'm just naming that because we know it's an alt it's all putting to the cosmos db right so shopping cart items out dot add async and then we pass in the item that it should be adding that's really what would happen at the end of that operation right so the commented out code matches the commented out code right so what we are doing however is we're seeing of course we know we get the data from the body we parse it accordingly and then we create a new item of type shopping cart where we pass in the name and the category that came in through our request and then we say document container dot create item async we give it the item and then we give it the partition key value now the relevance of this partition key value is that we are using the category that was sent over as the data right so when i set that category or when you're creating this item and that category we're creating it and we're setting that value so when we did our blog example we had used the id for both id and partition key in this case i'm showing a more practical example that you really want to slice it based on something like category or groupings right so we're using the category as the grouping and then once you do that we just return the okay object result with the item accordingly so either one of those lines would work relative to the uncommented or the commented out code so let us look at the update and because i removed the category from the update shopping cart item we're getting this error but when we get there we can look at it now i'm not going to spend time looking at the alternatives for the put and the delete you can go to and research those i'm just going to press ahead and show you how i have done it so i updated the route or i need to update the route to include the category right so i did not put in the category because the way we're doing it we always need a partition key so i need to extend this to the category of course the method is put so we're getting the request data parsing it over and then i'm going to save our item so i'm going to go and fetch the item from the database so we're using the same code that would have used in the get single right but this time the partition key is coming in from our parameter category or well just the same way so i need to make sure i put string category all right and then once it finds the item or not it's going to check okay if it found it then we move on to say item.resource so the data after it has fetched it the actual data is stored in item dot resource right so that is why we returned item dot resource up top and not just the item i don't know if i pointed that out earlier so item.resource and then we update whatever we know we need to update we know we're only the updating the collected so if you extend it to have name and whatever it would be item.resource.that property and then we await documentcontainer.opsert item async where we send back the item.resource pretty much so after we update item.resource we send it back and then that is what we're going to return anyway as the updated data in the delete we once again update the root so we're taking the category as our partition key and then we're just going to say await document container delete item async and we're saying we're deleting a shopping cart item we want to delete the id and that particular partition key and then we return the okay result so that's basically it for this operation all right guys so let us test it out anything we do anytime we do something cool we have to test it right so i'm going to just bring up postman and i already did a test with the post where i created apples and i gave it a category fruit here is a successful return we can go and get so this is getting all and i have two records in there i have the sandwich and i have apples one is in the category food one is in a category fruit so earlier when i was testing i was actually using needs and wands as my test and what i noticed was that it actually returned a 500 right so i have a correct id and incorrect partition key so that really should give me a 404 it means you cannot find what i'm looking for a 500 indicates that there's a problem on my server which is not accurate so if you look over here you see that it's actually throwing an extension an exception because the http client that is making the call to cosmos db has a method in there that says insure or a property that says ensure success code so if it sees anything other than a 200 or one of those 200 response codes it's actually going to throw an exception so even though it is saying that it's a 404 it's throwing an exception which is manifesting as a 500 to the client which we don't want so what i've done is to refactor it a bit so i'm showing you the code that is being called and that is throwing an exception my refactor would have me do a try catch and make that call inside of the try then i return the ok object result and then for the catch i'm going to say catch the cosmos exception in the form of an object called e so cosmos exception is the custom exception that is being thrown by that method and then when the status code is equivalent to and we can just use the built-in status code enum for not found then we want to return a new 404 right so that is my little refactor so i'm going to restart this and try that again so if i execute this again let me just make sure that this is running so if i execute this again and press send now there's no instance or there's no indication of an exception in the log and we're getting a 404 so that's much better right so i wanted this as food so let me try a cart request that should not give a 404 or a 500 and there we go we can retrieve the record successfully now let's try a put so initially i had the category in that i'm going to take that out and i'm going to just leave it at collected is true let us update our id value so the id and the partition key is needed for the put let me put both and then update so now you see that this is true so initially we know it was false right now we can see that it is true so the update works and then let us delete and once again we need to put in our id and the partition key for the delete so let me just do that and that's a 200 okay so if i try to get again then i only get one so all of our crud is working with our cosmos db of course if you want to further validate this you can bring up the emulator create look in the mla to make sure it's there and then do all of your adjustments accordingly play around with it explore see what is possible all right guys so we just went through quite a workout setting up our application to use cosmos db right so let us just quickly go through some of the ui changes that have to be made since we updated the routes information for some of our endpoints like we changed uh the get to also need the partition key stuff like that so of course the endpoints will need to be updated accordingly so in our client app we can leave the root api endpoint or the base address as is but then in our component i am going to make some adjustments to the update and the delete right so for the update we had said that yes we take the id but we also want the category so i already have access to the item so i'm just going to say slash add-on the category value also and the same for the delete we're just going to add on the category and that's really all there is to updating these endpoint calls of course if you are extending it um to you know have like a details page where you click and see just the detail of one record then you'll need to consider that let me just delete that dead piece of code and show you another update that i made initially i had this as value equals and it was bound to the bool but that should be checked all right so the input type checkbox checked is equal to whatever value that is and then we have that event and nothing changes for anything else so i'm just going to quickly test this out all right so that is our user interface i'm going to test this again blazer test um with cosmos bb and the category would be random create shopping cart item there we go all right of course we could always update the code that it empties out the text boxes as long as something is added successfully now before um you would have noticed that yes it was calling but the check value wasn't showing when it was true or not so we just updated that so if i check this one let me just bring up the console window so you see that it is going to call the update there it is the put was called successfully so if i navigate away from that page and come back it's going to run a fresh query and sometimes when you interfere with the in with the console it pauses but there it is that's the first query and now the check value is showing so if i delete we can see that the function was called but this is not redrawing so i can probably revisit that but if i navigate away and come back and allow it to run the get then we see here that it actually was deleted so we can probably update the ui code to redraw properly after a delete so the quick and easy fix for that is to modify our on click event callback method so instead of doing the way that we did with the event args and then we called the method name here where you're just going to have our add sign open parentheses then open and close so it's more like a delegate function and then we're delegating it to our delete clicked item right so pretty much that will just solve that redrawing issue because the way that the component loads the way we were doing it before it would actually try to reload everything before it actually registered that the items list was updated right so another thing that you might see me do is use a list instead of an array that really has no material effect i just tend to prefer lists both areas might be more efficient that's besides the point at this at this time so that's how you can get that delete to redraw the page properly but that's really it for the changes required to our client app all right guys so let us get started with our deployment so we're going to right click our function up and go to publish and then we get this wizard so we want to publish the azure we select that and then we need to specify a target now i may have inadvertently mentioned earlier in this course that if you're using windows then you may want to use c sharp and then you can use other languages for other platforms the reality however is that.net is actually cross-platform so c-sharp will work as well on windows as it will unmark and linux that's reality so your function app at the basic level can be deployed on the windows version of this function app or on the linux version of this function up just the same way that python java and typescript and javascript and any other language can also be supported you also have options to publish them as containers with with azure container registry which can allow you to host your docker image however i'm going to proceed with windows so after selecting windows we can now view or search for function apps so i already have a function app that we had created from the start but i'm not going to use that i want to create a brand new one so i'm going to click create a new function up and then it's going to ask me for the name so i'm going to say shopping cart hyphen api the subscription name of course at this point you may be prompted to sign in with your azure account so you can proceed to do that i'm going to leave it in one of the existing resource groups there we go function up rg if you don't have any resource group you can actually just click new and then create a new name and then we have our plan types so remember that we have the consumption plan the premium plan and the app service plan so just to recap what the plan types are and the different pros and cons of each the consumption plan is the serverless plan it's the most affordable plan that's two pros and a con is that it actually has limitations with the execution time so after about five minutes or so the whole app will actually wind down so it will kind of de-allocate those resources and then when you make another request it will take time to spool up again so of course for testing and for quick wins that would be a good approach however for a real scenario in a production setting where you need maximum efficiency and maximum uptime you would probably want to use premium where it does not wind down the resources you have dedicated resources at all times and you can access vnets and other resources on a network at a network level of course this costs a bit more your other option would be if you use an app service plan so maybe you have like an app service running a website already or another api you could actually just deploy it onto that plan also so i'm going to go with the consumption plan so after you select that you choose your location of course and for me that would be east us too and then you choose your storage account i only have one so that can remain and then we go ahead and click create and after that is completed we're led back to this dialog box where we can choose to run from package file so that is ticked and it is recommended pretty much what it's saying is that it will actually deploy more like a zip file with all of the required files the dlls and resource files that we need and it will mount like an image of the app instead of the actual files being there so without trying to understand the intricacies of it i'm just going to leave it ticked as it is stated that it is recommended so i follow their recommendation then we can hit next and then here they want us to decide do you want to publish like a regular website so before there was cicd this is how we used to publish it would generate a publish file deploy all of the files to a particular place whether on the network or your machine and then you can copy and paste them to the destination or do you want to use ci cd with github so i've already added this to github um if you want you can always go ahead and do that you can add the source control using this um option that would have been in the bottom right hand corner of visual studio after you do that and you upload it to github then you can probably come back here right so i'm going to use ci cd with github actions and then finish so that means each time i check in a change it will actually trigger a deployment now we're led to our final screen where they're just giving us a summary of everything that has taken place so it's actually going to add this new file which is called a yaml file or a yml file which basically has all the deployment instructions that github is going to use to determine what needs to happen we also get a preview of the url that will be generated for our azure app so everything that we need we can access it live through that url that's where our api will be accessible and down here we'll see some of the dependencies so application insights needs to be configured let's go ahead and do that remember that we would want to have that for the logging so you can actually just go ahead and click next through this wizard and allow it to finish and once you've done that it will show you a green tick that's configured they're also showing you that they will replace the azure storage settings for us right so locally we're using the emulator but once we deploy we'll know that it should be using the real storage account all right so with all of that done and if you wanted to modify the yaml file for whatever reason you can go to more actions click edit and it's showing you what is required right so like i said let me like i said this will actually be triggered when we do a check-in so if i open the git changes window you'll see that it's adding all of these changes and then i'm going to say deployment activity or deployment commit and then i'm going to just commit all and the sync save all changes and allow it to push to the repository so we can jump over to the repository in github and we can just click that little dot that appears beside the check-in or the commit number so if i do that and click details we'll jump over to that cid ca cicd screen so let's give it a few to finish up and after a few minutes it should be done all right so let us jump over to our dashboard and let us look at our resources so i'm going to go to all resources and i should see my new function up there we go now before we go any further with the function app remember that we do need a cosmos db or whatever kind of database you would have used you do need that to exist in order to have that connection ready for testing so i'm going to jump over to our dashboard and i already created the cosmos db but i'm going to walk you through the process regardless so you know you can go to all services and then you just go and search for cosmos db once you have the cosmos db you would create and then we're using the core sql now on this screen you choose the resource group so i recommend that you choose the same resource group as your function up of course you enter an account name now the naming is very strict so you can't use any capital letters or anything so i would have called it shopping cart items of course that's really just an account name so you don't necessarily have to call it that um but you give it that name if it is it's not available you just try and make it a little more personalized right and then you choose a location that's best for you once again i recommend choosing a location that is as close as possible to where the function app was deployed so once you do that you can choose whether you want the provision throughput or serverless and if you choose serverless obviously you don't have the phone the options below but if you choose provision throughputs then you can choose a player that apply that free tiered discount now what i have experienced in the past is that i wasn't able to proceed with the free tier discount on the second and third try so i'm just pointing that out if you try it with it applied and you end up having a failed deployment you'd have to delete that resource come here try again and i recommend that you click do not apply of course if it's your first time then you can leave it on that but if you choose do not apply then it will start costing you or you can just choose serverless you also can change the backup policy to save costs so since this is not a production system you don't necessarily have to go geo redundant you can do local redundant backup storage so it costs less money but if it's production then i recommend that you leave that on gear redundant so those are the real two real settings that you would have to make sure are there and what i'll do is jump over to my already provisioned as cosmos db account once you're here you want to go to the data explorer now this data explorer looks just like what we would have experienced with the emulator so you create your new database according to how you would have written the code of course and pretty much whatever you did in the emulator you just repeat those steps to create your database and the container as well as the partition key inside of this one right so with all of that set up we want to make sure that we get the correct connection string so here's that primary connection string we can copy that and then go back to our function up so i'm just going to go over to the dashboard jump over to the function up and then inside of the configuration we need to add that primary connection key so remember in our code we would have set up that we need to look in the app settings.json so locally that would have been the local dot settings.json file that's what it recognizes the app settings however in a deployed setting we have to set up our application settings so you just say new application setting give it the appropriate name relative to what we wrote in the code which was cosmos db connection and then you paste that primary connection key here so i already did that here it is i added that manual the cosmos db connection and the value so once you have all of that set up then you can proceed to test so to test we can click on functions and that will give us a list of all the functions that have been deployed in this app if i click any one of them let's start with the get shopping cart items here you'll see like a little dashboard of all the executions you've kind of seen how this dashboard looks already if you go to code and test note that you cannot write code for the function here because it was actually deployed from visual studio so any edits have to happen in visual studio it's really just mounting it and it has a bare minimum as far as the configurations are concerned so here it's showing you that the script is really loading from that dll that's the compiled version of the whole source code right so that is what we would see there but if we were to go back and get the function url then we would be able to get that url which we can just paste in the browser to test so if you want to monitor as we saw before you can just go to monitor and go to logs and when that is connected and up and running you can proceed to test so i'm just going to open in a new browser a tab sorry and paste so here i'm getting that empty array bracket but then if i look in the log out see that it called the function and there was nothing to share right so that means using postman or any other api tool i can actually simulate the same kind of kind of calls that i'm used to so here is where we would have created a shopping cart item instead of posting to the local host i'm going to replace all of that with our new url to our azure websites send the request and there i have it it's a 200 okay response so that means if i refresh this request to get all now i'm seeing the object in the database so that's it really for publishing our function app to microsoft azure all right guys so in this lesson we're going to be bringing our client up up to speed so what i've done is i jumped over to visual studio i have up the program cs file and i'm going to change this path from the localhost functions path to our deployed functions path so from the dashboard i'm just going to grab this url as that is our new base url and i'm going to replace this line of code so i'll just duplicate the original and comment that out and paste this new address so with that pasted let's test it out so i'm just going to right click this project and go to debug and start with our debugging and when we navigate to our fetch data page you can see here i'm getting an error so if i go on inspect and look in the console to see why you're seeing that it failed to fetch that's all it's really saying but if you look above that you see that it says access to fetch at that address from this origin has been blocked due to a course policy so what mentioned course policies earlier of course is the cross origin resource security protocol in other words two things have to be on the same network or domain or framework infrastructure for access to be granted so what i need to do is jump back over to the functions up go down to the course policy there we go and then add the url and once that is added i'll save and then i'll come back and try again and notice there's no error and now i have data coming from azure all right all right so now that i've verified that this is working let's jump back over to the program.cs and what i want to do is configure this that if we're in production we use the production link if we're in there we use the dev link all right so that i can just set it up one time so i'm going to say uh give me a var base address and to create a variable called a base address and set it to be this new uri or rather let me set it to be this string which is our local and then i'm going to say if our builder dot host environment dot is well this is the development address so i'm going to say is production all right so this is a nice easy way to check if you're in production when you're using a blazer web assembly app and then i'm just going to say the base address is equal to this string which is our published address so then i can have one line where i say builder.services http client base address is new uri off the base address value so with that done it will be dynamic there might be more elegant ways to do that but for now this will work so let us publish our app so i'm just going to right click go down to publish uh sorry publish there we go and then i'm going to create a new profile so the profile that's there is already for the the function up but this time i'm creating a new profile i'll choose azure and i'm going to publish it to another app service and it's going to ask which app service instance is here that have a few already i'm not going to use any of those or i probably can that's fine i'm just going to do a new one so i'm going to create a new one um this would be the app service plan right so the app service plan is pretty much the base and then you deploy to that base this app service itself so i'm going to create a new hosting plan i'm going to call it shopping cart list and put it in the same resource group as our function app so the importance of assigning stuff to the same function to the same resource group would be that if you no longer wanted the app and the resources for this app you can just delete the resource group and everything in it and that's a nice easy way to clean up so i'm just going to put it in there also and i'm going to place this on a free plan so by clicking new i choose my location and then i can go down to the free plan but of course based on your context you don't want to choose the plan that best suits your needs so i'm going to go with free for this demo i'm going to click create and when that is done i can just go ahead and hit next and i will publish this with the same cicd setup as the function up so i just click finish all right and then this summary page is letting me know what the pending url for my app is going to be so at that point i can just go to get changes and say set up deployment for blazer commit all and sync and then if you want you can jump over to github and watch that deployment and it's done so let's jump over to the published site remember we can just get that url from the publish profile or go to your portal dashboard and get it from the newly deployed app and let's go to fetch data just to make sure it can communicate and it cannot can you guess and tell me why well if you guessed that the course policy is not set up then you guessed correctly right so here we can see it it's still complaining about course why is it complaining about course because that's a brand new domain name separate from the one that we had used initially right so i have to go back over to the function up jump over to the course policy configuration and add this new url and let me just make sure i meet the format save try again and enjoy the fruits of our labor so that is us publishing our client-side app which is communicating with our function app now there are other things that we can do with this other configurations that we can make along the way to make this a bit more seamless i will discuss them later on but for now we have successfully published both the api and our client app
Info
Channel: Trevoir Williams
Views: 8,833
Rating: undefined out of 5
Keywords: Creating a Web API with Azure Functions, Azure Cosmos DB Core (SQL) API and Blazor, Trevoir Williams, How to create Web API with Azure Functions, Web API, Azure Functions, Blazor WebAssembly App, Test and Add Blazor WebAssembly UI, Add Azure Cosmos DB, Create API Routes, Web API Tutorial, azure functions, azure cosmos db, azure function web api, how to create an api in azure, azure functions cosmos db
Id: XybqmjuZw-g
Channel Id: undefined
Length: 95min 8sec (5708 seconds)
Published: Sat Aug 06 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.