Durable queue in Azure Service Fabric using WebJobs, Part 2: Web API

This the second post in a series about Durable queue in Azure Service Fabric using WebJobs:

Now let’s create another stateless service which will host the Web API. I used default Visual Studio template called “Stateless ASP.NET Core”. You can find how it configures Kestrel as an underlying application web server here.

This service/Web API will have a controller responsible to convert requests into queue messages, enqueue them. For the sake of demonstration, this would be an incidents management system:

  • Read requests go through cache. High volume can be handled. Cache is populated from storage during cold start.
  • Write requests go though cache as well and update it, then update storage. Implemented using HTTP verb PATCH to better support concurrency.
namespace DurableQueueSample.StatelessWebApiService.Controllers
  public sealed class IncidentController : Controller
    public async Task Get(Guid incidentId)
      var actorId = new ActorId($"GET+{incidentId}", Uri("fabric:/DurableQueueSampleApplication/ActorStatefulService");
      var actor = ActorProxy.Create(actorId);

      var incident = await actor.GetIncident(incidentId);
       =return Ok(incident);

    public async Task Patch(Guid incidentId, string name, string value)
      var patchId = Guid.NewGuid();
      var patch = new IncidentPatch(patchId, incidentId, name, value);

      var messageContent = _jsonConverter.Convert(patch);
      await queueClient.EnqueueClient(queueName, messageContent);

      var url = _urlBuilder.BuildUrl(StatusController.GetStatusRouteName, new { patchId })!
      return Accepted(url);

In contrast to ASP.NET Web API which doesn’t have a built-in method to return 202 Accepted so you would need to roll out custom extension method, ASP.NET Core does have a family of them. We need the one which accepts Uri without object.

Method Get() routes request directly to the stateful service hosting requests processing actors. While method Patch() enqueues requests, doesn’t wait its processing to be completed, returns the control immediately after Azure Queue client acknowledges message reception. This way client browser also doesn’t wait, can check the status by following provided url, e.g. /api/status/?patchId={patchId}. However other clients, if try to retrieve the incident before the patch has been applied, might see outdated values. This is the price for update requests asynchronous processing.

Here’s how the queue trigger function looks like:

namespace DurableQueueSample.StatelessWebJobsService.Functions
  public sealed class IncidentPatchFunction
    public async Task Handle(
      [QueueTrigger(queueName)] IncidentPatch patch,
      TextWriter dashboardLogger)
      var actorId = new ActorId($"PATCH+{patch.IncidentId}", Uri("fabric:/DurableQueueSampleApplication/ActorStatefulService");
      var actor = ActorProxy.Create(actorId);
      await actor.UpdsteIncident(patch.IncidentId, patch.PropertyName, patch.PropertyValur);

Next time: we’ll create another, this time stateful service which will host the actors.

This entry was posted in Programming and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.