Building a Serverless REST API With Azure Functions From Scratch

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we'll build a serverless rest API with Azure functions only from new project to Microsoft Azure deployment and 100 Cloud native so don't miss it [Music] hey there and welcome to the code wrinkles Channel building rest apis is something that we do fairly often as developers and we usually use asp.net core duties to an extent that it has become mainstream and it is for amateurs but will bring everything to the next level as we'll build right now a serverless rest API with Azure functions only 100 Cloud native and if you think that what we'll build here is just a dummy HTTP triggered functions then you are totally wrong we'll build a fully functional crud endpoints in our Azure functions and to do this we'll have to dive deeper into some very important topics like how do we use dependency injection in Azure functions how do we use entity frame or coordinator functions and obviously also how do we use Azure keyword to safely store our secrets everything will be covered during this video and believe me this journey is not necessarily complicated but it is paved with a lot of different challenges so the goal here is to explain everything as clear as possible and as in-depth as possible so that you can go in your project and confidently use Azure functions so let's get to work usually in my day-to-day work I like to always start by creating the needed Microsoft Azure resources and that's why I have created a very basic setup where I have an SQL database an SQL server and a key Vault and the storage account and what we'll do here is we'll go on and create our Azure function app so we'll search for function and this should be the one and then click create now during the creation process the Rams are there are some important things that we need to take into considerations first of all the subscription and the resource Group that's everything fine and the next thing is we need to give a name to our function app so let's try with this one and then there are some things that we need to be careful about so the runtime stack that's where we say exactly okay do we want to have.net node.js python Java and so on and so forth obviously we will want to have.net now there is the important part like the version when we think about function apps there are actually two types of functions that can run in function apps there are in process functions that run in the same process as the host and there are isolated functions that run in a different process dedicated process so not in the same process as the host the thing here is that for instance in the in-process function in Microsoft Azure they always supports just lts.net releases so it means that we would need to take here the net 6 because that one is an LTS on the other hand if we want to use isolated then we have or we can use also.net 7 for instance or releases that are not LTS however there are some differences between how in-process functions work and how isolated functions work even to the code that we need to write so in this case or in this video I will focus on in process functions and therefore I will choose this.net 6 LTS and then the region I'll choose West Europe as always the operating system I want to be Windows that's okay then let's click next for storage and Azure functions already also need a storage account now here by default they say or the function says that they would or it would like to create a new storage account but I already have a storage account so I will just choose this existing storage account and I will click here on next then enable Public Access this is something that we want on by default in this case because we want to be able to call our rest API from our Azure or from Postman so outside the Azure function itself next to networking here we'll leave everything as it is right now I will also go on and create a new application inside then for Diagnostics here I would like to have this on disabled I don't want to integrate with GitHub actions right now then just review the tags review the function and create it now that the function app is created I am back here in my Resource Group and I want to go on and go to this function app because there are some things that we need to configure here first of all we want to integrate this function app to use Azure key Vault and if you remember in order to do this we need to come here to Identity and we want to enable this system assigned manage identity so we'll just click on Save here we click on yes and now I can copy this object principle ID now that I have this The Next Step would be to go to the Azure keyboard because we need to enable an access policy for this Azure function so let's go to our Azure keyword resource and then we need to go to access policies and here we need to add an access policy for our system assigned manager identity that we have assigned to the function app we'll just click here on create we will need just get a list because we will need to be able to also read the value then next here we can search by the object principle ID that we have copied earlier and that's our function app so next and right now it should be okay now let's move over to visual studio and create a new Azure functions project let's name it serverless rest YouTube and here there's another Choice once again we have defined in when we created the Azure function that we need to use.net6 because we want it to have an in-process functions here and that's why here we also need to make sure that we choose.net6 because that's what we want to use and then each function has different Triggers on which it can get executed and to create a rest API what we need to do is to create an HTTP trigger so this is actually what we have here by default and then we can simply just click create okay so we have here our first function but what I would like to do is simply delete it right now I want us to actually concentrate on two very important things like this host.json file and this local dot settings Json files they are very important now the host.json file is a Json file where we can configure different options for the host itself so once we deploy these Azure functions the options or the things that we configured here in the host.json will actually be also executed and will work will take effect also in the Azure function function that is that runs in our Azure web app however there is also this local dot settings.json file and this file is very important because this file is very useful to you if you want to debuggle when you debug your Azure functions locally you can specify for instance what options do you need or what technique do you need for that Azure function to work properly now in our case what we will need is the key Vault URL so what we'll do is We'll add the keyboard URL here in this local.settings.json so let's have a comma here and just add here our new options which is the keyboard URL but this means that we need to set the exact same option also in our Azure portal so let's go back to this report and let's open once again our function app and to configure the exact same options or settings that you have in your local environment for debugging in your function app you need to come here to this configuration and in the function app configuration you will see just in a few seconds that you can add your own configuration information to it but the only thing that we need to do here is new application setting then for the name we need to use the exact same name that we have used locally because our code will rely on this specific name and obviously we'll also need to use the exact same URL because we'll use the exact same Azure key Vault let's click on OK and let's click on Save okay let's move back to visual studio right now let's close all these files that we have here and the next step that we need to think about here is we need to install a bunch of nuget packages that we will use throughout this video so let me go here to management get packages and let's start first we'll use Azure identity because we will use Azure identity to create a new default credential so that we will be able to access the Azure key Vault so let's just install this one then what we'll also need is security.kivault.secrets so it's this one because we need to be able to read the secrets and then and we'll need this Microsoft dot Azure dot function extensions so that's the next one that we need and then we need a bunch of packages for Microsoft Entity framework core we need the first one and here is one other caveat where we need to be very careful remember that we have our function runtime using.net so dot net 6 so the LTS version of that the current LTS version by the time of recording but this means that we need to be careful because Entity framework we need to also install the.net fix version so I will install the latest.net6 version of that so let's install and then we'll also need the SQL server and once again we need to be careful exactly at the same thing we want to install the.net6 version and we will choose the latest.net 6 version for ef6 version let's install and we should be good to go right now next we can create the classes that we will need for this rest API to work and first of all we need obviously a Source on which we want to create crowd endpoints and we'll keep it simple and we'll think about a product so with all this class product and it will be a product.ts I would also like to make it public even though internal should also work and here I'll just copy in some properties that I have already prepared like an intid name and the price now that we have this we also need a DB context to be able to write or to purchase new products to the database and also update them or read them so let's add here on your class and I'll call it FDB context let's also make it public let's inherit a DB context and add the using statements that are missing and then we will configure here a very regular DB context just we are accustomed to in asp.net core where we'll take in some DB context options and we'll pass them to the base class and we'll just have here a DB set for the products this time we won't perform any migration at the database in Azure is already up to date with the latest schema that we would need I'll be honest with you and I have prepared this before this video using an asp.net core project to add the migrations and update the database the reason for this is that to use everything in Azure functions requires a lot more tweaking on Entity framework core with design time Factory and running migrations and updating the database via code and that would be totally outside the scope of this video but if you would like me to cover this topic more in depth and please let me know in the comments and I'll consider creating a video on this now let's move on and take a look at how we can configure and use dependency injection in our in-process Azure function to add dependency injection to our in-process Azure functions we need to configure the host when it starts up to do this we will also need the help of a new class that we will add just now to create add new class and we will call this class startup because this is the class where we Define some things that need to be added during the startup process of the host and the way way we can make Azure functions aware about the fact that we want to configure the host we need to inherit this Base Class which is the functions startup that class contains an abstract method that we need to implement that method is this public override void configure and we have this I functioned host Builder which is similar to the web application builder in the sense that we can configure the Builder the only thing that we would like to do in this Builder is to add DB context to the dependency injection container so that we can inject it in the functions that we will create now in order to read or to get or to create an instance of the DB context or to add it to the dependency injection container we need to read the connection string and to read the connection string we need to connect to Azure key Vault so let's take this step by step first of all we will need to read this keyboard URL from our settings and the way we do this in Azure functions is or one way that we could do this in Azure functions is to use this environment and then get environment variable because the settings that you set in the localsettings.json files they will be available as environment variables and it also goes the same to the Azure portal so the settings that you set in the configuration as an application setting will be available to the function itself as environment variables so the code that we've written here will work both when we debug locally but also when we deploy to Azure the next step is to connect to our Azure key Vault and to be able to connect to the Azure key Vault we need what is called a Secrets client so that's exactly what we create here so new secret client and here is provide the URL the URI that we have ahead earlier and the default Azure credential the next logical step would be to just read the secret that is of interest to us and that is this SQL now here I say that this is a little bit funny because on the secret client we say this get secret delivery provided key for the secret and then we get this value which is if we hover the mouse on this is this a keyboard secret now this keyboard secret which has the name value here has another property that's also called value and that's the actual string that we are looking for in our case the connection string so I know it's a little bit funny but hey that's how it works and once we have everything in place we can add the DB context just like we do normally in an asp.net core application with Builder services at the big context and then opens use SQL Server here we are missing probably a using statement that we will need so let's just edit and now all error disappeared so we have configured the host we are ready with this now we would need to create some Azure functions that represent our API endpoints and this Bears a little bit more thought so what we'll have in the end is five crowd operations get all get by ID create update and delete and if we think little bit about the URLs that we will need for this rest endpoints or for discred actions will have just two different rest endpoints or two different URLs will have products and will have product slash ID Behind These two URLs we can group all the crud actions that we need under products we can group The create and the get all endpoints and under products slash ID we can group the update the delete and the get by ID therefore I'll create here two different Azure functions each one will be responsible to handle the requests for a certain URL obviously you could do this even differently you could create an Azure function for each crud endpoint that would also be totally fine so you have full freedom to design your functions the way that you think is best for your specific scenario now let's get back to work let's start with the first endpoint and remember we want what have Urinator function for this get all and create so let's click here on ADD and here you see that we have the option to add a new Azure function and that's exactly what we want to click and I will still keep here Azure function now the only thing is I will need to provide a name and I will use these products get all create so that I know exactly for which endpoints or for which Cloud operations this function is responsible so let's click add and here we are presented with this very simple wizard from here we will choose this HTTP trigger because we want this to be a rest API so we will receive HTTP calls therefore we need an HTTP trigger then the authorization level we have to create here function on Anonymous or admin now this authorization level is actually important we can also change it afterwards so there's no problem with that and we'll see exactly where we can do that however the main idea is that if we choose here function it means that for each call that we make to our Azure function so from a client in our case from Postman we would also need to provide a key now a key we can generate from the function app in Microsoft Azure and we can use this keynote and you also have the master key and that would correspond to the admin now for now we will want to just to concentrate on this very simple setup and make everything work you will choose as authorization level this Anonymous that doesn't require any type of key or any type of authorization to be able to perform the request obviously I want to emphasize this is not a secured approach and if you're building this in production you would have to choose here authorization level function and then you work with keys and even better you would probably need to have an API Gateway in front of this and make all the authorization at the API Gateway level not on the Azure function itself so let's click add and here we have added these very basic Azure function we'll probably delete a lot of things that we have here but I would like to go through some steps that we need to perform here or the very first thing that we need to do is we need to change a little bit how this class looks like because we need to be able to inject our entity frame or core DB context first of all we just need to make our class to be non-static the reason why we want to do this is because obviously we'll need to provide a DB context to private field for a DB context then we will get a DP content injected and we assign it to our private field so that we can use it in the function here now if it comes to the function itself I just want to spare a few words about what we have here first of all we have this attribute basically this is an HTTP request and that's decorated with an attribute I know it's quite long but that's the main idea of the attribute you have to specify a lot of different things in this specific trigger attributes now the first thing that we specify in this attribute is the authorization level and I told you earlier that we can customize that or we can change that and here is where you can change it so I if I want to change this to be authorization level function then I could simply just use this enum and choose from here function then the next thing that we find here in the trigger is the HTTP actions to which this function will be triggered so in this case we have get and post which corresponds to what we want to have in this function because if you want if we have a get we want to get all the products and if we have a post we want to create a new product and now for the route here this is also a very important part because here is where you can customize your exact route and we'll see a little bit later even including routing parameters now what we need in this case our Rock will be products Now by default the Azure function will work in a way that it will it will also have the API before product so it will in the end be slash API product but for us it's important right now just to concentrate on this product's part and then we also have this eye logger that will get injected by the host directly into this function now we will not use the logo right now so I will just delete this now as a next point I would like to implement the logic for our Azure function so I will delete everything that we have here and I will replace with the code that I have already prepared and I will go to this code line by line obviously first of all we need to make this method non-static because it needs to be an instance method so that we have access to the private field and in this case below that we perform here is very easy there are only one or one or two things that we need to be a little bit more careful about now the thing is that we will have here a little bit of different logic depending exactly if we have a get or if we have a post and that's where we have this if so we say that if the action for this HTTP request is post then in this case we want to create a new product to create a new product we need to read the HTTP body and to create a product from that specific body now here in Azure functions we we don't get this by default like we do it in asp.net core so that's why we create first of all a stream reader and we read the body with that specific stream reader and then we use Json convert and deserialize object and we use this generic version of the serialized object because we want to deserialize this to a specific product and obviously we provide here the stream reader that we get here now this means that when we add when we finish reading here we have a new product as you can see if we hover the mouth Mouse over it and then we can use the DB context to add the product and then we can save the changes and everything is done the only thing that it still remains to do is to return something now obviously we need to also return an i action result but the way that we usually return from asp.net core apis is not 100 exactly the same so we will have to return a new we need to create a new instance of created result now in this created result you would have to specify the fully qualified URL through which you can access the newly created resource for Simplicity reasons I have specified here only this product and then the body that will be placed in the HTTP response and then the other thing that we need to do here is if it is not a post and this function gets executed it means that it is a get and in that case the only thing that we want to do is to get all the products so we have these two list async we need to just use micros Entity framework and once we have all these products we can return an OK object result and with that specific product and with this our Azure function is ready so let's create a new Azure function here so add new and we'll create Azure function the name of the function this time will be products get by ID update delete because these are the current actions that we want to be handled in this specific function so we can click add here once again will have this HTTP trigger will check we will take the easy one or the simple one without open API and then we will use also Anonymous as authorization level and then we will just click edit and here we will need to perform mostly exactly the same things that we have done earlier so remove here the static also remove it from the method so that we don't get confused then let's adhere the private field in the Constructor let's remove the logger because we will not use the logger in this case this time we will also need to customize a little bit what actions do we want to listen to Because here we have the get in that case it is a get by ID but then we want to have a put and then we would also like to have a delete and then we also need to specify the route in this case our route will also have a routing parameter like this one let's maybe get these things on your line so route it would be here product slash ID here this ID this is a routing parameter and binding parameters in HTTP triggers Works more or less exactly the same that we are accustomed in asp.net course so that's why we specify this ID in curly braces now just like in asp.net core if we have this route param it means that we also have to specify for it is int ID so that it could bind to this integer ID so that we can get that information and work with that and now let's get rid of all this stuff here and we'll decrease replace this with our custom logic and what we have here for instance is okay if the method is get then we want to get by ID so in this case we have this product first or default async if it is now then we return a notepad result otherwise we return an OK object result then the second scenario that would be possible is that if the method is put it means that we need to do an update in that case just like we did previously it means that we need to also read the body so we need a stream reader then we use this Json converting with the serialized to our product and then we just also set the ID from the identifier that we have in the router that we make sure that we update the product that needs to be updated and then we'll add the database save the changes and we return a new OK object result if we want to delete on the other hand what we'll do is once again we'll look for the product in the database and then if the product is not we once again return a not found result but if we find a pro this product we just remove it we save the changes and then we return a null content result now let's go back here a little bit because we have forgotten here format but right now we should be actually good to go everything should be up and running and we can test this application however now that I'm about to run this application I remember that I forgot something very important and it has to do with dependency injections that's why I'm back here in the startup class because there is one other step that we need to perform for things to work so by default the Azure functions host will not know that okay we have this startup class where we have overridden this configure method that it needs to execute so we need to specify this using this attribute which is the function startup and we see is only specify exactly where the startup class is that we want to execute the configured method on when the host is created and configured and now we should be really ready to go with all the needed information so let's run the application so now the application is up and running and as you can see we already have two functions so we see that already in the console and we also see the URL with the available HTTP actions or methods that are available for those specific URLs so let's move over to postman where I have already created this so we have this localhost and then the Portland API slash products and let's create a new product and here let's say then hold wrinkles let's maybe put here a different price we will just sit here locally these two end points so the create and the get all endpoints and then when we deploy to Azure we'll test also the other endpoints and here we have the result we see that the resource was created with this ID Pi let's also test this get all and we see that we have these two products that are created and this is the one that we have just created and let's maybe also even try this other one with the ID with the get and it should be also return this product it was just created we see that everything is working right now locally let's move back here let's stop these Azure functions because we don't want to run it anymore and what I would like to do here right now is to deploy it to Azure and I will do this deployment from visual studio so I will click here on publish and then I'll choose here Azure because in Azure is where I want to publish I want to publish the Azure function app that runs on Windows because that's what I have and then he receives loading and we can already see that it sees the function app that I already have and then I just click here on finish and it will do the deployment and I will be just right back when the deployment is completed so the function app is now deployed to maps of azure and this is the URL that we have here in Microsoft Azure so I will go over to postman first let's run this get all and we see that it Returns the exact same result let's maybe also run get by ID so we just specify an identifier and that should be okay now let's also test the update one so let's have it with put let's just replace the URL and here I would like to have the name it would be like this so then and this other one let's make it 220 and then let's click just scent and right now right now we are making the calls directly to our Azure function app as you can see here in that URL and now let's make a get once again and we know that it is with id5 and we should be able to see the updated product which is indeed the case we see the updated value and also the name was updated and last but not least let's also try to delete so let's just click on delete and it was 204 no content so deleted let's now maybe try it to another one to get but let's get all the products so let's send the request and in this case we see that once again we just have one product in the database because the other one is deleted that's it you made it till the end don't forget to hit the thumbs up button and like this video so that others might Discover it easier and if you're for the first time on the channel hit the Subscribe button and the notification Bell so that you are always notified when there's new content here and if you have any question or just want to get in touch with me don't be shy and head over to the comment section and leave me a comment I would be more than happy to get in touch with you this being said thank you very much for watching and until the next time I wish you the very best
Info
Channel: Codewrinkles
Views: 19,811
Rating: undefined out of 5
Keywords:
Id: 3HZjmYohlgc
Channel Id: undefined
Length: 28min 27sec (1707 seconds)
Published: Sun Apr 16 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.