Skip to content

Instantly share code, notes, and snippets.

@justinyoo
Created April 22, 2020 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinyoo/01426032d1ee6886796d9cb72e048dd9 to your computer and use it in GitHub Desktop.
Save justinyoo/01426032d1ee6886796d9cb72e048dd9 to your computer and use it in GitHub Desktop.
Building RequestBin with Durable Functions
[FunctionName(nameof(CreateBin))]
public async Task<IActionResult> CreateBin(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route="bins")] HttpRequest req,
[DurableClient] IDurableClient client)
{
...
}
[FunctionName(nameof(CreateBin))]
public async Task<IActionResult> CreateBin(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route="bins")] HttpRequest req,
[DurableClient] IDurableClient client)
{
var binId = Guid.NewGuid();
var bin = new EntityId("Bin", binId.ToString());
...
}
public interface IBin
{
void Add(BinItem item);
void Reset();
}
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Bin : IBin
{
[JsonProperty("history")]
public virtual List<BinItem> History { get; set; } = new List<BinItem>();
public void Add(BinItem item)
{
if (item == null)
{
return;
}
this.History.Insert(0, item);
}
public void Reset()
{
this.History.Clear();
}
[FunctionName(nameof(Bin))]
public static Task Run([EntityTrigger] IDurableEntityContext ctx) => ctx.DispatchAsync<Bin>();
}
[FunctionName(nameof(CreateBin))]
public async Task<IActionResult> CreateBin(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route="bins")] HttpRequest req,
[DurableClient] IDurableClient client)
{
...
await client.SignalEntityAsync<IBin>(bin, o => o.Add(null));
...
}
[FunctionName(nameof(AddHistory))]
public async Task<IActionResult> AddHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", "put", "patch", "delete", Route="bins/{binId}")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
var history = new BinItem();
using (var reader = new StreamReader(req.Body))
{
history.Timestamp = DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");
history.Method = req.Method;
history.Headers = req.Headers.AsEnumerable().ToDictionary(p => p.Key, p => string.Join(";", p.Value));
history.Queries = req.Query.ToDictionary(p => p.Key, p => string.Join(";", p.Value));
history.Body = await reader.ReadToEndAsync();
}
...
}
[FunctionName(nameof(AddHistory))]
public async Task<IActionResult> AddHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", "put", "patch", "delete", Route="bins/{binId}")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
...
var bin = new EntityId("Bin", binId);
await client.SignalEntityAsync<IBin>(bin, o => o.Add(history));
...
}
[FunctionName(nameof(GetHistory))]
public async Task<IActionResult> GetHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route="bins/{binId}/history")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
var bin = new EntityId("Bin", binId);
...
}
[FunctionName(nameof(GetHistory))]
public async Task<IActionResult> GetHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route="bins/{binId}/history")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
...
var entity = await client.ReadEntityStateAsync<Bin>(bin);
var payload = entity.EntityState;
var result = new JsonObjectContentResult(HttpStatusCode.OK, payload);
return result;
}
[FunctionName(nameof(ResetHistory))]
public async Task<IActionResult> ResetHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route="bins/{binId}/reset")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
var bin = new EntityId("Bin", binId);
...
}
[FunctionName(nameof(ResetHistory))]
public async Task<IActionResult> ResetHistory(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route="bins/{binId}/reset")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
...
await client.SignalEntityAsync<IBin>(bin, o => o.Reset());
...
}
[FunctionName(nameof(PurgeBin))]
public async Task<IActionResult> PurgeBin(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route="bins/{binId}/purge")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
var bin = new EntityId("Bin", binId);
...
}
[FunctionName(nameof(PurgeBin))]
public async Task<IActionResult> PurgeBin(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route="bins/{binId}/purge")] HttpRequest req,
[DurableClient] IDurableClient client,
string binId)
{
...
await client.PurgeInstanceHistoryAsync($"@{bin.EntityName}@{bin.EntityKey}");
var result = new NoContentResult();
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment