Interview question
Return 202 for a durable background job
Persists a job and outbox command before returning a status URL for long-running work.
TL;DR
Persists a job and outbox command before returning a status URL for long-running work.
202 Accepted, durable job state, outbox dispatch, status resources, ownership, and retry-safe workers.
Practice the problem like a real interview: restate, reason, implement, and test.
POST /reports creates a durable queued job and returns 202 with a Location header. A protected status endpoint exposes queued, running, completed, or failed without leaking another user's job.
The API process restarts immediately after returning 202; the persisted outbox still dispatches the report command and status remains queryable.
I model the job as an API resource rather than an in-memory task. One SaveChanges stores both the queued job and outbox message, then a separate dispatcher delivers work after commit.
app.MapPost("/reports", async (CreateReportRequest request,
ClaimsPrincipal user, AppDbContext db, CancellationToken ct) =>
{
var userId = user.RequireUserId();
var job = ReportJob.Queue(userId, request.Filters, TimeProvider.System.GetUtcNow());
db.ReportJobs.Add(job);
db.OutboxMessages.Add(OutboxMessage.Create(
"report.requested", new { job.Id, job.UserId, job.Filters }));
await db.SaveChangesAsync(ct); // Job and dispatch intent commit together.
return Results.AcceptedAtRoute("GetReportJob", new { id = job.Id },
new ReportJobResponse(job.Id, "queued", null));
}).RequireAuthorization();
app.MapGet("/reports/{id:guid}", async Task<IResult> (Guid id,
ClaimsPrincipal user, AppDbContext db, CancellationToken ct) =>
{
var userId = user.RequireUserId();
var job = await db.ReportJobs.AsNoTracking()
.SingleOrDefaultAsync(x => x.Id == id && x.UserId == userId, ct);
return job is null ? Results.NotFound() : Results.Ok(ReportJobResponse.From(job));
}).WithName("GetReportJob").RequireAuthorization();
202 means accepted for processing, not completed. Durable state and outbox delivery survive process failure; the worker still needs idempotent claiming, bounded retries, and a terminal failure policy.
Task.Run inside the endpoint.Move to the linked follow-up, next path step, prerequisite, or deeper variant.
Practice the next layer of the same subject.