Writing Azure Web Services
Azure provides a fully managed platform for building and hosting web applications and services through Azure App Service. With App Service, developers can quickly create modern web applications and RESTful APIs with .NET, .NET Core, Java, Node.js, PHP or Python. Several templates are available to scaffold basic web apps along with tools for DevOps, monitoring, authentication and authorization. In this article, we will explore how to write and deploy Azure web services using .NET Core.
Getting Started
The best way to start creating an Azure web service is by using the Azure CLI or Azure Portal to create an App Service plan and web app. An App Service plan determines the size and pricing for the compute resources used by your web app. The basic pricing tier is suitable for development and testing purposes. Once the resources have been created, you can either develop your code locally and deploy it or use App Service for quick deployment using source control.
For local development, install the .NET Core SDK and create a new .NET Core web API project using the dotnet new webapi command. Configure the project to be hosted as an Azure Web App by adding a web.config file with the required configuration settings. This allows published code to run correctly on Azure. Folder structures follow typical .NET conventions with Models, Controllers and other logical groupings. Add NuGet packages like Microsoft.AspNetCore.App if not included by default.
Expose Data as RESTful Services
The goal of a web service is to expose application functionality through a standardized interface like REST. With REST, resources are accessed via unique URLs and support create, read, update and delete (CRUD) operations through HTTP verbs like POST, GET, PUT and DELETE. Entity Framework Core is a popular ORM for .NET that allows mapping database entities to objects and CRUDing them using LINQ queries.
Define model classes for database entities and add the DbContext class to map models to a database. Configure the connection string in appsettings.json. Controllers handle requests and call services which encapsulate business logic. Create a base ApiController class for common methods. Add controller actions mapped to routes that call services to perform CRUD operations on models. Services abstract data access using DbContext and EF Core.
For example, to expose a Products resource:
hy
Copy
// POST api/products
[HttpPost]
public IActionResult Create([FromBody] Product product)
{
_productService.Create(product);
return Ok();
}
// GET api/products
[HttpGet]
public IEnumerable
{
return _productService.GetAll();
}
This creates a standardized REST interface to work with product data without knowing database implementation details. Services handle actual data access code.
Authentication and Authorization
Web APIs need mechanisms for clients to securely authenticate and authorize access. Azure App Service offers several options out of the box for adding authentication:
Azure Active Directory (AAD) – Authenticate users through an Azure AD tenant. AAD handles user management, SSO and access tokens.
Individual User Accounts – Store users locally, handle sign up/in through default UI.
Social Logins – Facebook, Google, Twitter etc.
Once authenticated, you need to authorize access to controller actions/resources. Attach the [Authorize] attribute to controllers/actions to require a valid auth token. You can also check the user’s roles, permissions etc in authorization policies.
Another option is JSON Web Tokens (JWT). Generate and validate JWT access tokens on your own instead of relying on AAD. Implement token generation on login and validation inside controllers. Add claims containing roles, expiration etc in tokens.
Caching and Performance
Caching improves web service performance by avoiding expensive database calls. Output caching stores complete HTTP responses reducing server workload. Entity Framework second level caching caches query results in memory. For example:
clojure
Copy
[ResponseCache(Duration = 60)]
[HttpGet(“{id}”)]
public Product GetById(int id)
{
return _context.Products.Include(x => x.Details)
.FirstOrDefault(x => x.Id == id);
}
This caches GetById responses for 60 seconds. Entity Framework also has builtin support for caching queries – enable via DbContextOptions.
For fast cache lookups, use distributed caching like Azure Cache for Redis or the Cache service. Store/retrieve objects in cache vs database. Configure cache expiration/invalidation for stale data. Websockets/server-sent events are also options for realtime/low latency communication instead of REST polling.
Logging and Diagnostics
Capturing diagnostic logs is essential for monitoring, auditing and debugging web services. Use logging frameworks like NLog or Serilog with NuGet packages. Define log levels and targets like file, console or Application Insights. Log service methods, exceptions, requests etc.
Application Insights is a comprehensive monitoring service for web apps. Add the Application Insights SDK for automatic collection of request/dependency telemetry, exceptions and custom events out of the box. View real user monitoring (RUM), availability and performance trends in portal dashboards. Integrate with other services like Azure Monitor for metrics.
Error Handling
Proper error handling prevents exceptions from crashing services and ensures clients receive meaningful responses. Define custom exception classes inheriting from Exception for different error types instead of throwing generic ones.
Copy
public class InvalidCredentialsException : Exception
{
public InvalidCredentialsException() : base(“Invalid credentials provided”) {}
}
Use exception filters to catch exceptions and return standardized error responses:
typescript
Copy
[ExceptionFilter]
public class ApiExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
context.Result = new JsonResult(new {
error = context.Exception.Message
}) {StatusCode = 500};
}
}
Handle expected errors like 404s separately by returning specific response payloads instead of exceptions.
Deployment and Hosting
When the service is ready for production, deploy it to Azure App Service. Publish from Visual Studio using Publish option or deploy via Git if source control integrated. App Service handles auto scaling, high availability, security updates etc. Enable staging environments for pre-production testing.
Configure deployment slots like Production and Staging that share resources but deployed code/configurations can differ. Swap slots atomically during deployments. Set deployment credentials, source control publish profiles and CD workflows. integrate builds/deployments with DevOps tools like Azure Pipelines.
App Service offers auto scaling by increasing/decreasing instance count based on predefined metrics like CPU, memory usage etc. Configureautoscale settings. Configurecustom domain names and SSL bindings. Set up CI/CD pipelines for continuous delivery of feature updates safely to production.
Monitoring and Management
Once deployed, monitoring provides insight into service performance, errors and usage. Application Insights captures telemetry out of the box as discussed earlier. Others tools that can be used are:
Azure Monitor – Metrics on CPU, memory, requests, exceptions etc across all Azure resources
Log Analytics – search, analyze logs from all sources like Application Insights, Linux servers
Alerts – Configurable rules based notifications on metrics, logs through various channels
Autoscaling – Scale instances automatically based on metrics
Application Gateway WAF – Web application firewall rules to block attacks
Use API management for publishing, securing, managing APIs. Features include request/response caching, quotas, authentication, developer portals etc. API proxies deployed separately from backing services.
Key Takeaways
Azure provides a fully managed Platform as a Service for developing, deploying and managing web applications and RESTful services in a scalable and secure manner. Developers gain productivity using pre-built Azure services for authentication, logging, caching, monitoring etc without managing infrastructure. Focus is on writing code and business logic while Azure handles operational aspects. With continuous integration/delivery, services can reliably deliver new features to users with high availability and performance.
