Exploring Azure Functions HTTP Trigger Using EF Core

Introduction

 
The HTTP trigger lets you invoke a function with an HTTP request. These HTTP triggers let you build a serverless API  and respond to the webhooks.
 
In case you haven’t read my previous article, I would recommend you to read it here.
 
You can find the source code here.
 

Attributes

 
Attribute Property Description
Route It defines the route template on which the endpoint is listening. The default value of the route is set to api/<FunctionName>.
AuthorizationLevel Azure Function protects your HTTP trigger using Authorization keys. Authorization Level comes with three flavors
– Anonymous: No key is required.
– Function: A specific function key is required. This is the default value if none is specified.
– Admin: A master key is required.
Methods This is used to define HTTP verbs for the functions.
 
Coding
 
Let's begin by creating a new Azure Functions project by select the trigger type as HTTP.
 
Add Nuget package
  1. Microsoft.EntityFrameworkCore.SqlServer  
  2. Microsoft.EntityFrameworkCore.Design  
  3. Microsoft.EntityFrameworkCore.Tools  
  4. Microsoft.Azure.Functions.Extensions  
Add the entity Model,
  1. public class Employee {  
  2.     public int Id {  
  3.         get;  
  4.         set;  
  5.     }  
  6.     public string Name {  
  7.         get;  
  8.         set;  
  9.     }  
  10.     public int Age {  
  11.         get;  
  12.         set;  
  13.     }  
  14.     public double Salary {  
  15.         get;  
  16.         set;  
  17.     }  
  18.     public string City {  
  19.         get;  
  20.         set;  
  21.     }  
  22.     public string State {  
  23.         get;  
  24.         set;  
  25.     }  
  26. }  
Next, I’ll create a plain context for the data model to interact.
  1. public class EmployeeContext: DbContext {  
  2.     public EmployeeContext(DbContextOptions < EmployeeContext > dbContextOptions): base(dbContextOptions) {}  
  3.     public DbSet < Employee > Employees {  
  4.         get;  
  5.         set;  
  6.     }  
  7. }  
Write Function code to inject context
 
To inject the EmployeeContext in our HTTP Function, we first need to register the context in configure method of the FunctionStartUp.
  1. [assembly: FunctionsStartup(typeof(HttpTriggerVerify.Startup))]  
  2. namespace HttpTriggerVerify {  
  3.     public class Startup: FunctionsStartup {  
  4.         public override void Configure(IFunctionsHostBuilder builder) {  
  5.             string SqlConnection = Environment.GetEnvironmentVariable("SqlConnectionString");  
  6.             builder.Services.AddDbContext < EmployeeContext > (x => x.UseSqlServer(SqlConnection));  
  7.         }  
  8.     }  
  9. }  
  1. public class HttpTriggerVerify {  
  2.     private readonly EmployeeContext employeeContext;  
  3.     public HttpTriggerVerify(EmployeeContext employeeContext) {  
  4.             this.employeeContext = employeeContext;  
  5.         }  
  6.         [FunctionName("HttpTriggerVerify")]  
  7.     public IActionResult GetEmployees(  
  8.             [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req, ILogger log) {  
  9.             log.LogInformation("C# HTTP trigger function processed a request.");  
  10.             var employees = employeeContext.Employees.ToList();  
  11.             return new OkObjectResult(employees);  
  12.         }  
  13.         [FunctionName("SaveEmployee")]  
  14.     public async Task < ActionResult > SaveEmployeeAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req ILogger log) {  
  15.         string requestBody = await new StreamReader(req.Body).ReadToEndAsync();  
  16.         var data = JsonConvert.DeserializeObject < Employee > (requestBody);  
  17.         await employeeContext.Employees.AddAsync(data);  
  18.         await employeeContext.SaveChangesAsync();  
  19.         return new OkResult();  
  20.     }  
  21. }  
In this example, we are using two functions
  • GetEmployees: Get all the employees from the DB
  • SaveEmployee: Insert the employee related information to DB
Here, I am using the Authorization level as Anonymous for simplicity purposes.
 
Executing EF Core Migration
 
Now, run the EF core migration by using the below commands.
  1. //For Mac  
  2. dotnet ef migrations add InitialContext  
  3. For Windows  
  4. add-migrations InitialContext  
After running the migration command, an error is thrown suggesting it's unable to find the project dll in the netcoreapp folder. But, you can find the project dll file inside the netcoreapp’s bin folder.
 
Unfortunately, the design time tools like EF core migration expect the dll’s to be present in the root of build target. To make the EF core migration happy, we need to add post build event to copy the dll to the root of build target.
  1. <Target Name="PostBuild" AfterTargets="PostBuildEvent">  
  2.    <Exec Command="cp "$(TargetDir)bin\$(ProjectName).dll" "$(TargetDir)$(ProjectName).dll"" />  
  3. </Target>  
Again after running the migration script, EF core is now complaining about not being able to find the desired context. We can fix it by using IDesignTimeDbContextFactory<T>.
  1. public class EmployeeContextFactory: IDesignTimeDbContextFactory < EmployeeContext > {  
  2.     public EmployeeContext CreateDbContext(string[] args) {  
  3.         var optionsBuilder = new DbContextOptionsBuilder < EmployeeContext > ();  
  4.         optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("SqlConnectionString"));  
  5.         return new EmployeeContext(optionsBuilder.Options);  
  6.     }  
  7. }  
After running the migration script, everything seems to be working perfectly! Now, update the database with the latest migration
  1. //For Mac  
  2. dotnet ef database update  
  3. //For Windows  
  4. update-database  
Now, I can see Employee table is being added to the DB.
 
Finally, we have managed to put all the code changes in place. Run the application and verify the GetEmployees and SaveEmployee methods are working as expected.
 
I hope you like the article. If you found this article interesting then kindly like and share it.