Creating a Serverless RESTful API with Azure Functions Part 2 – Creating the API

On today’s post we will be creating our Serverless REST API with Azure Functions. We will be doing that with Visual Studio.

This post is part of a series where the first part should be read beforehand.

Creating the “basic MM Service”

For this we have to install the latest Azure Functions Tools and an operative Azure Subscription. We can do this from Visual Studio, from either “Tools” and then “Extensions and Updates”, we should either install or update the latest Azure Functions and Web Jobs Tools” (if we are using VS 2017) or if we are in VS2019, we should go to Tools, then “Get Tools and Features” and install the “Azure development” workload.

We should create a new “Azure Functions” template based Project.

01 create Azure Function

And select the following options:

  • Azure Functions v2 (.NET Core)
  • Http trigger
  • Storage Account: Storage Emulator
  • Authorization level: Anonymous

02 AZ Func creation config.PNG

Then we can click create and just run it to see it working. Pressing F5 should start the Azure Functions Core Tools which enables us to test our functions locally, a convenient feature I’d say. Once starting we should see a console window with the cool Azure Functions logo flashing.

03 AZ functions core tools.PNG

then once the startup has finished copy the function URL, which in our case is “http://localhost:7071/api/Function1”.

04 AZ functions core tools URL.PNG

To try this from  a client perspective we can use a browser and type “http://localhost:7071/api/Function1?name= we are going to build something better than this…” but I’d rather use a serious tool like Postman and issue a GET request with a query parameter with key “name” and the Value “we are going to build something better than this…”.  This should work right away and also some tracing should appear on the Azure Functions Core Tools. The outcome in Postman should look like:

05 consuming our Micky Mouse with Postman.PNG

Or if you opted for the browser test “Hello,  we are going to build something better than this…” – which we are going to do in short.

We just saw a “Mickey Mouse” implementation but if you are like me, that won’t satisfy you unless you add some layers in to decouple responsibility and some interfaces because, er… we like complication right? 😉 –  Not really but I thought it would be good to put in code which does something simple but is still as SOLID as I can get without too much effort.

What are we going to build?

We are going to create a REST API that exposes a simple list of categories (a complex POCO with Id and Name), then the API Controller which will be the main API interface and it will delegate obtaining the Data to a Service and the Service to a Repository.

And we will stop here, so this will be completely on memory so no Database will be hurt in the process, also no Unit Of Work will Need to be implemented as well.

We will create some interfaces and configure/register them with Dependency Injection, which uses the ASP.NET Core DI basically.

I have a disclaimer which is that WordPress has somehow disabled HTLM editing so I can’t put code from GIT or have a nice “code view” in place which is… making me think of switching to another blog provider… so if you have any suggestion, I’d appreciate you mention it to me with a comment or directly.

 

Creating the “boilerplate”

We will start by creating the POCO (Plain Old CLR Object) class, Category. For this we can create a “Domain” Folder and inside it create a “Models” Folder where we will place this class:

    public class Category 
    {
        public int Id { get; set; } 
        public string Name { get; set; }
    }
Next we will implement the Repository Pattern which is used normally to abstract us from the data management for a concrete Entity. Usually we encapsulate on this classes all the logic to handle data like Methods to list all the data, create, edit, delete or recover a concrete data element. These operations are usually named CRUD, for Create/Read/Update/Delete and are meant to issolate data acess operations from the rest of the application.
Internally These Methods should talk to the data storage but as we mentioned, we will create an in memory list and that will be it.
Inside the “Domain” Folder we will create a “Repositories” Folder, on it we will add a “ICategoryRepository” interface as:
    public interface ICategoryRepository
    {
        Task<IEnumerable<Category>> ListAsync();
        Task AddCategory(Category c);
        Task<Category> GetCategoryById(int id);
        Task RemoveCategory(int id);
        Task UpdateCategory(Category c);
    }
And a class CategoryRepository which implements this interface..
    public class CategoryRepository : ICategoryRepository
    {
        private static List<Category> _categories;
        public static List<Category> Categories
        {
            get
            {
                if (_categories is null)
                {
                    _categories = InitializeCategories();
                }
                return _categories;
            }
            set { _categories = value; }
        }

        public async Task<IEnumerable<Category>> ListAsync()
        {
            return Categories; 
        }

        public async Task AddCategory(Category c)
        {
            Categories.Add(c);
        }

        public async Task<Category> GetCategoryById(int id)
        {
            var cat = Categories.FirstOrDefault(t => t.Id == Convert.ToInt32(id));

            return cat;
        }
        public async Task UpdateCategory(Category c)
        {
            await this.RemoveCategory(c.Id);
            Categories.Add(c);
        }

        public async Task RemoveCategory(int id)
        {
            var cat = _categories.FirstOrDefault(t => t.Id == Convert.ToInt32(id));
            Categories.Remove(cat);
        }

        private static List<Category> InitializeCategories()
        {
            var _categories = new List<Category>();
            Random r = new Random();

            for (int i = 0; i < 25; i++)
            {
                Category s = new Category()
                {
                    Id = i,
                    Name = "Category_name_" + i.ToString()
                };

                _categories.Add(s);
            }

            return _categories;
        }
    }
This Repository will  be talked to only by the Service, whose responsibility is to ensure the data related Tasks are performed agnostically from where the data is stored. As we mentioned, the Service could Access more than one repository if the data was more complex. But, as of now it is a mere passthrough or man-in-the-middle between the API Controller and the Repository. Just trust me on this… (or search for “service and repository layer”) a good read on this here
There we have all wired by an in-memory list of categories List<Category> named oportunely Categories, which is populated by by a function named InitializeCategories().
So, now we can go and create our “Services” Folder inside the “Domain” Folder…
We should add a ICategoryService interface:
    public interface ICategoryService
    {
        Task<IEnumerable<Category>> ListAsync();
        Task AddCategory(Category c);
        Task<Category> GetCategoryById(int id);
        Task RemoveCategory(int id);
        Task UpdateCategory(Category c);
    }
Which matches perfectly the functionality of the Repository, for the reasons stated, but the objectives and responsabilities are different.
We will add a CategoryService class which implements the ICategoryInterface:
    public class CategoryService : ICategoryService
    {
        private readonly ICategoryRepository _categoryRepository;

        public CategoryService(ICategoryRepository categoryRepository)
        {
            _categoryRepository = categoryRepository;
        }

        public async Task<IEnumerable<Category>> ListAsync()
        {
            return await _categoryRepository.ListAsync();
        }

        public async Task AddCategory(Category c)
        {
            await _categoryRepository.AddCategory(c);
        }
        public async Task<Category> GetCategoryById(int id)
        {
            return await _categoryRepository.GetCategoryById(id);
        }
        public async Task UpdateCategory(Category c)
        {
            await _categoryRepository.UpdateCategory(c);
        }
        public async Task RemoveCategory(int id)
        {
            await _categoryRepository.RemoveCategory(id);
        }
    }
With this we should be able to implement the Controller without any Showstopper..

Adding the necessary services wiring up

This is where everything comes together. There are some changes though, due to the fact that we will be adding dependency injection to setup the services. Basically we are following the steps from the official Microsoft how-to guide which in short are:

1. Add the following  NuGet packages:

  • Microsoft.Azure.Functions.Extensions
  • Microsoft.NET.Sdk.Functions version 1.0.28 or later (at the moment of writing this, it was 1.0.29).

2. Register the services.

For this we have to add a Startup method to configure and add components to an IFUnctionsHostBuilder instance. For this to work we have to add a FunctionsStartup assembly attributethat specifies the type name used during startup.

On this class we should override the Configure method which has the IFUnctionsHostBuilder as a parameter and use this to configure the services.

For this we will create a c# class named Startup and put the following code:

[assembly: FunctionsStartup(typeof(ZuhlkeServerlessApp01.Startup))]

namespace ZuhlkeServerlessApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<ICategoryService, CategoryService>();
            builder.Services.AddSingleton<ICategoryRepository, CategoryRepository>();
        }
    }
}

Now we can use constructor injection to make our dependencies available to  another class. For example the REST API which is implemented as an HTTP Trigger Azure Function will resolve the ICategoryServer on its Constructor.

For this to happen we will have to change how this HTTP Trigger is originally built (hint: It’s Static…) so we need it to call its constructor..

We will remove the Static part on the generated HTTP Trigger function and the class that contains it or either generate a complete new file.

We will either edit it or add a new one with the name “CategoriesController”. It should look like follows:

    public class CategoriesController
    {
        private readonly ICategoryService _categoryService;
        public CategoriesController(ICategoryService categoryService) //, IHttpClientFactory httpClientFactory
        {
            _categoryService = categoryService;
        }
..

The dependencies will be resolved and registered at the application startup and resolved through the constructor each time a concrete Azure Function is called as its containing class will now we invoked due it is no longer static.

So, we cannot use Static functions if we want the benefits of dependency injection, IMHO a fair trade off.

In the code I am using DI on two places, one on the CategoriesController and another on an earlier class already shown, the CategoriesController. Did you realize the constructor injection?

 

Creating the REST API

As stated on the earlier section, we removed the static from the class and the functions.

Now we are ready to finish implementing the final part of the REST API… Here we will implement the following:

  1. Get all the Categories (GET)
  2. Create a new Category (POST)
  3. Get a Category by ID (GET)
  4. Delete a Category (DELETE)
  5. Update a Category (PUT)

Get all the Categories

Starting with getting all the categories, we will create the following function:
        [FunctionName("MMAPI_GetCategories")]        
        public async Task<IActionResult> GetCategories(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "categories")]
            HttpRequest req, ILogger log)
        {
            log.LogInformation("Getting categories from the service");
            var categories = await _categoryService.ListAsync();
            return new OkObjectResult(categories);
        }
Here we are associating “MMAPI_GetCategories” as the function Name, adding “MMAPI_” to relate them together in our Azure UI, as everything we deploy as a package will be put togher and using a naming convention will be convenient for ordering and grouping.
The Route for our HttpTrigger is “categories” and we associate this function to the HTTP GET verb without any Parameters.
Note here we are using async as the Service might take some time and not be inmediate.
Once we get the list of categories from our service, we return it inside the OkObjectResult

Create a new Category

For creating a new Category we will create the following function:
        [FunctionName("MMAPI_CreateCategory")]
        public async Task<IActionResult> CreateCategory(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "categories")] HttpRequest req,
    ILogger log)
        {
            log.LogInformation("Creating a new Category");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject<Category>(requestBody);

            var TempCategory = (Category)data;

            await _categoryService.AddCategory(TempCategory);

            return new OkObjectResult(TempCategory);
        }

This will use the POST HTTP verb, has the same route and will expect the body of the request to contain the Category as JSON.

Our code will get the body and deserialize it – I am using the Newtonsoft Json library for this and I delegate to our Service interface the Task to add this new Category.

Then we return the object to the caller with an OkObjectResult.

Get a Category by ID

The code is as follows, using a GET HTTP verb and a custom route that will include the ID:

        [FunctionName("MMAPI_GetCategoryById")]
        public async Task<IActionResult> GetCategoryById(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "categories/{id}")]HttpRequest req,
            ILogger log, string id)
        {
            var categ = await _categoryService.GetCategoryById(Convert.ToInt32(id));            
            if (categ == null)
            {
                return new NotFoundResult();
            }

            return new OkObjectResult(categ);
        }

To get a concrete Category by an ID, we have to adjust our route to include the ID, which we retrieve and hand over to the categoryservice class to recover it.

Then if found we return our already well known OkObjectResult with it or, if the Service is not able to find it, we will return a NotFoundResult.

 

Delete a Category

The Delete is similar to the Get  by ID but using the DELETE HTTP verb and obviously a different logic. The code is as follows:
        [FunctionName("MMAPI_DeleteCategory")]
        public async Task<IActionResult> DeleteCategory(
            [HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "categories/{id}")]HttpRequest req,
            ILogger log, string id)
        {
            var OldCategory = _categoryService.GetCategoryById(Convert.ToInt32(id));
            if (OldCategory == null)
            {
                return new NotFoundResult();
            }

            await _categoryService.RemoveCategory(Convert.ToInt32(id));
            
            return new OkResult();
        }
The route is the same as the previous HTTP Trigger , we also do a Retrieval of the Category by Id. Then the change happens if we find it, then we ask the Service to remove the category.
Once this is complete we return the OkResult. Without any category as we have just deleted it.

Update a Category (PUT)

The Update process is similar as well to the delete with some changes, Code is as follows:

        [FunctionName("MMAPI_UpdateCategory")]
        public async Task<IActionResult> UpdateCategory(
            [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "categories/{id}")]HttpRequest req,
            ILogger log, string id)
        {
            var OldCategory = await _categoryService.GetCategoryById(Convert.ToInt32(id));
            if (OldCategory == null)
            {
                return new NotFoundResult();
            }

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            var updatedCategory = JsonConvert.DeserializeObject<Category>(requestBody);
            await _categoryService.UpdateCategory(updatedCategory);

            return new OkObjectResult(updatedCategory);
        }

Here we use the PUT HTTP Verb, receive an ID that indicates us the category we want to update and in the body, just as with the Creation of a new category, we have the Category in JSON.

We check that the Category exists and then we deserialize the body into a Category and delegate to the service Updating it.

Finally, we return the OkObjectResult containing the updated category.

 

Deploying the REST API

We could now test it in local as we did at the beginning but what’s the fun of it, right?
So, in order to deploy it to the cloud we will Need to have a Microsoft Account logged in our Visual Studio that has an Azure subscription associated to it.
We will build it in release and then go to our Project, right click and choose “Publish..”
06 Publishing our REST API.PNG
We will choose “Azure Function App” as publish target and “create new”. Also it is recommended to mark the “Run from package file” which is the recommended option.
07 Publishing configuration 01.PNG
And click on “create profile”. There we will be presented into the profile configuration, where I recommend we create all the resources and do not reuse.
Regarding the Hosting Plan, be sure to check the “Consumption plan” which has like 1Milion of API Calls before any charge is made, which is convenient for testing purposes I’d say.
08 Publishing configuration 02.PNG
Note that when I publish this post this app service will be long gone so no issues in Posting it :).
Once configured we should click on “Create” and wait for all the resources to be created, once this is done the Project will be built and deployed to Azure.

Checking our Azure REST API

Now it is a good moment to move to our favorite web browser and type portal.azure.com.
We can move right away to the resource group we created and into the App Service created. Sometimes, when Publishing the Functions are not populated.
if that happens, don’t panic, just re-publish it again. The Publish view should look like:
09 Publishing again if no functions.PNG
A bit after, we should be able to see our services in our App Service:
10 Our REST API in azure.PNG
To try this quickly, we should go to the GetCategories, click on the “Get function URL” and copy it.
11 Get function URL
Then we can go into our friend PostMan, set a GET HTTP request and paste the URL we just copied in the, er, URL Field. And click Send.
We should see something like:
12 Trying from Postman out new Azure Function REST API
We could also test this on a web browser and on the Test section on the Azure portal, but I like to test Things as close as customer conditions.
As next steps I throw you the challenge to test this Serverless REST Api we just build in Azure with Azure Function Apps. I’d propose to try to create a new Category such as “999” – “.NET Core 3.0” then retrieve it by ID, then modify it to “.NET 5.0”, retrieve it and end up deleting it and trying to retrieve it again just to get the “NotFoundResult”.
So, what do you think about Azure Functions and what we just have build?

Next..

And that’s it for today, on our next entry we will jump into API Management .

Happy Coding & until the next entry!

 

 

 

 

 

Silverlight DataGrid – Issues solved!!

Today is a happy day….  

I am actually battling with a Silverlight business application with some interesting design & behavior – in fact it is a migration from a VB6.0 App.. but the design of the screens is not bad and it’s pretty useful to the task they are designed for. 

One of the most costly things I’ve suffered is that I had to show off some information grouped and totalized (nothing strange here, you just have to search a bit and you know the how-to) and also each group of information could have different format on the same column…. and oh my, this has been a real killer… 

I tried to change it programmatically but the Binding is bound to the column… so I tried to change the binding, first through the StringFormat but… hey! it is not bindable! Bummer… then I tried to use a custom Converter and bind the ConverterParameter but it also happened not to be bindable – or I did not find how to implement it. I tried also to implement a custom Converter deriving from FrameworkElement and IConverter so I could create a bindable property for using it instead of the ConverterParameter…. but that didn’t work out properly… 

Until I found a gem, the “Silverlight MultiBinding” solution that a smart guy, Colin Eberhardt conceived & developed to implement a similar binding model to that of WPF, with more funcitons and to be clear, more mature. Silverlight team, we need that on SL ASAP if we are to build serious SL business apps… if not some developers can get near to crazy to solve some “customer needs”… like I have ;). 

Regarding the MultiBinding, you can read from Colin on his blog here: http://www.scottlogic.co.uk/blog/colin/2010/08/silverlight-multibinding-updated-adding-support-for-elementname-and-twoway-binding/ 

Gladly I’m not alone as “Full Databinding Support” is the top requested feature on the Silverlight Feature Suggestions forum here:  http://dotnet.uservoice.com/forums/4325-silverlight-feature-suggestions, with over three thousand points, it’s the Nº1!!. 

Wich includes requests for fabulous features like: 

+ ValueConverter ConvertParameter binding.
+ StringFormat binding.
+ Strongly typed DataBinding support (intellisense).
+ Conditional Binding.
+ Binding to dynamic objects .
+ More extensibility.
+ Etc.. 

Regarding to my solution I implemented it on the DataGridTemplateColumn for each column I needed to format conditionally, considering also that some columns will need to be editable, so I had to use the usual binding for the editable template even that the TwoWay binding works on the Multibinding implementation but I found no way to keep the format from being reset (by now the TwoWay multibinding requires that all the properties are TwoWay). You can see the XAML code next: 

<data:DataGridTemplateColumn Header=”Budget” > 

<data:DataGridTemplateColumn.CellTemplate>

<DataTemplate>

<TextBlock TextAlignment=”Right” > 

<multibinding:BindingUtil.MultiBindings>

<multibinding:MultiBindings>

<multibinding:MultiBinding TargetProperty=”Text” Converter=”{StaticResource MultiBindingGenericConverter}” >

<multibinding:MultiBinding.Bindings>

<multibinding:BindingCollection>

<Binding Path=”Budget” />

<Binding Path=”Budget_Format” />

</multibinding:BindingCollection>

</multibinding:MultiBinding.Bindings>

</multibinding:MultiBinding>

</multibinding:MultiBindings>

</multibinding:BindingUtil.MultiBindings>

</TextBlock>

</DataTemplate>

</data:DataGridTemplateColumn.CellTemplate>

<data:DataGridTemplateColumn.CellEditingTemplate>

<DataTemplate>

<TextBox TextAlignment=”Right” Text=”{Binding Budget, Converter={StaticResource RoundedConverter}, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}” >

</TextBox>

</DataTemplate>

</data:DataGridTemplateColumn.CellEditingTemplate></data:DataGridTemplateColumn>

So if you have a similar scenario, I’d recommend Colin’s solution.

Other issue I had with the DataGrid was with the Virtualization – it’s virtually impossible to deactivate. Also the search for a solution on this was” a bit chaotic… “

I was lucky to find out this gem here http://forums.silverlight.net/forums/t/101075.aspx on which Xusan is telling us not to deactivate it but to change its structure and take out the component that provides the virtualization, changing its ControlTemplate.

That saved my day as the DataGrid really is not “Recycling” but “Reusing”, which I think should be changed or made  optional. As this can be Ok for performance reasons but on others you can end up coding a huge clean-up function that will kill the performance of the virtualization…  if there is a quick way of “cleaning” a row or cell, it would be great this was as fast as possible…

Well, will keep on finishing my DataGrid based project management Silverlight Bizz app 😉 

Have fun!

Simple trick for getting right the DataGrid’s SelectedItem

I have been developing a Silverlight business application and one of the problems I have found is the “inconsistency” of the DataGrid… at least of some of its behaviors, when I click on a row, I expect that the SelectedItem (the clicked one) is set on the corresponding DataGrid property. 

But it does not. at least not “always”, lets be clear maybe I’m doing something wrong but this randomness on this behavior is driving me crazy, if I click on a Grid row, it should select it and mark the SelectedItem on the corresponding property, right? 

I have been doing so in the MouseLeftButtonUp of the DataGrid, so that’s what I expected but… sometimes it had it, sometimes not… bummer! 

So I have been trying to detect why is this happening but could not discover it… maybe I’m wrong in any of the assumptins but meanwhile, I got a workaround that does really work :). 

The following code explains it all… 

void datagrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { 

  if (datagrid.SelectedItem == null){ 

 

      FrameworkElement fe = (e.OriginalSource as FrameworkElement); 

 

      FrameworkElement feCell = (fe.Parent as FrameworkElement); 

 

      var myData = feCell.DataContext; 

  } 

} 

Basically I check first If I have the SelectedItem set, sometimes it is, so then I avoid doing the following trick.

The “trick” mainly gets the originalsource that is launching the event, that is the control inside the cell of the grid,  most of times it will be a TextBox. Second I get the Parent, with this I am getting to the Cell.

Note that if you have a complex structure you should set up a recursive function to go “up” until you get a reference for the cell.

From the cell you have the datacontext which is the item whe should have got from the SelectedItem property.  you should cast it to the inherent type and get any value you need from it.

Also, please note that the DataContext could be caught from the first element (OriginalSource) but it’s more ellegant to get it from the Cell, and if it is a complex custom cell this also asures that it gets the DataContext properly.

And yes, it works 100% 😉

Happy coding!

PS: If somebody knows what I have done wrong or why the DataGrid.SelectedItem Property does not return the clicked item, I would be happy to hear. 🙂

Trick for solving WCF RIA Services issue..

I am having the following issue: Sometimes, when I am issuing a DomainService call using WCF RIA Services, I got the callback right but the loadoperation I have assigned has no results, meaning no entities are returned and the “IsComplete” property is false. 

The following code resumes what I am doing, including the LoadOperation definition, the calling function and the callback function: 

LoadOperation lo; 

private void CallDomainService(){ 

DomainContext dc =  new DomainContext(); 

lo = dc.Load(dc.GetDataQuery()); 

lo.Completed += new EventHandler(lo_Completed); 

} 

And it executes well and calls properly lo_completed… 

void lo_Completed(object sender, EventArgs e){ 

     if ((lo != null) && (lo.IsComplete == true)){

      if ((lo.Entities !=null) && (lo.Entities.Count() >= 1))         //Get the returned entity or whatever..

   }

} 

The issue is that I am getting properly the details of the load Operation, but some random times, it does not return the object properly, it is not null but its .IsComplete property is False and the Entities collection is empty, though that it has had been processed properly by the server.

The trick or workaround here is to get, in this exact case, the loadoperation from the server, which is a reference to the right load operation. The code should be like this:

LoadOperation<EntityType> lo2 = (LoadOperation<EntityType>)sender;

if ((lo2.IsComplete) && (lo2.Entities.Count() >= 1)) {

   EntityType Entity = lo2.Entities.First();

 

}

And with this, problem solved.

Are you having this random issue or others? anybody found why this is happening?