Start learning free

LESSON 154 OF 173 · BACKEND: SHIPPING IT

Health and Readiness in C#

Practice

On a server, the shop usually runs as several copies behind a load balancer, which shares the visitors' requests between them. Every few seconds, the load balancer and the platform that starts the copies ask each copy two questions over HTTP.

Health: are you alive? If a copy doesn't answer 200, the platform restarts it, so keep this check simple: a restart can't fix a database problem. Readiness: can you serve requests right now? If a copy doesn't answer 200, the load balancer sends it no requests until it does. Here you really try what the app needs, and answer 503 Service Unavailable when it fails.

For example, an app that keeps uploads in a folder could check that the folder is there:

app.MapGet("/uploads-ok", () => {
    try {
        Directory.GetFiles("uploads");
    } catch (IOException) {
        return Results.Json(new { uploads = "missing" }, statusCode: 503);
    }
    return Results.Json(new { uploads = "ok" });
});

The check plays the load balancer: it asks /health and /ready, takes away the disk with shop.db, asks again, then brings the disk back. When your code is done, it prints:

Every few seconds, each copy of the shop is asked:
GET /health -> 200 {"status": "ok"} -> alive, keep it running
GET /ready -> 200 {"status": "ready"} -> ready, the load balancer sends it requests
The disk with shop.db is gone:
GET /health -> 200 {"status": "ok"} -> alive, keep it running
GET /ready -> 503 {"status": "not ready"} -> not ready, the load balancer sends it no requests for now
The disk is back:
GET /ready -> 200 {"status": "ready"} -> ready, the load balancer sends it requests

Your task: the app is already created for you. Add GET /health, which answers {"status": "ok"}, and GET /ready, which opens shop.db, runs SELECT COUNT(*) FROM products and answers {"status": "ready"}, or {"status": "not ready"} with status 503 when it throws a SqliteException.


Assignment
Follow the Coding Tutorial to add the /health and /ready routes.


Hint
Don't check the database in /health. In /ready, run a query, not just db.Open(): when shop.db is missing, opening a SqliteConnection quietly makes a new, empty file. Microsoft.Data.Sqlite reports SQLite's errors as a SqliteException.


STEP 1 OF 10
    Ctrl + Enter to check

    Ship Health Probes in C#

    Keep going with C#1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free