# Exercise: an API Client

Write a ProductClient for your products API, with one async method per endpoint, 404s turned into null or false, and a low-stock report built with LINQ. Tests give it a fake API, so they need nothing running.

Journeyman · C# · REST API · Updated November 2, 2026

Your products API from *Exercise: Northwind Web API* needs a client: a C# class that other programs use to read and change products, without knowing anything about URLs, status codes or JSON. You'll write `ProductClient`.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-an-api-client](https://github.com/ask-codey/exercise-an-api-client), also linked from the **Exercise** box beside the lesson. Click **Code**, then **Download ZIP**, and unzip it into your `bootcamp` folder. Or clone it with Git. Then open `NorthwindClient.slnx` in Visual Studio.

| File | What's in it |
|---|---|
| `NorthwindClient/Product.cs` | A product, shaped like the API's JSON |
| `NorthwindClient/ProductClient.cs` | For you to finish. Its requirements are in the comment at the top. |
| `NorthwindClient/Program.cs` | A small program that uses the client against the running API |
| `NorthwindClient.Tests` | Tests that give the client a fake API |

## What to do

| Method | Sends | Returns |
|---|---|---|
| `GetAllAsync(categoryId)` | `GET api/products`, or `?categoryId=1` | The products |
| `GetByIdAsync(id)` | `GET api/products/1` | The product, or `null` on `404` |
| `AddAsync(product)` | `POST api/products`, the product as JSON | The product the API sends back, with its new id |
| `UpdateAsync(product)` | `PUT api/products/1`, the product as JSON | The updated product the API sends back, or `null` on `404` |
| `DeleteAsync(id)` | `DELETE api/products/1` | `true`, or `false` on `404` |
| `LowStockAsync(threshold)` | (uses `GetAllAsync`) | Products under the threshold, fewest first, then by name |

Any other unsuccessful answer, such as `400`, `409` or `500`, throws an `HttpRequestException`.

Run the tests with **Test > Run All Tests**. Then start your products API, check the address at the top of `Program.cs`, and run this program with **Ctrl+F5**.

## Hints

- **The tests need no API.** They give `ProductClient` an `HttpClient` that talks to a `FakeApi` class, which records each request and answers with whatever status and JSON the test chose. That only works because `ProductClient` asks for its `HttpClient` instead of making one.
- **`GetFromJsonAsync`** suits `GetAllAsync`; it throws on any failure, which is what you want there.
- **Where `404` is a normal answer**, use `GetAsync`, `PutAsJsonAsync` or `DeleteAsync`, check for `HttpStatusCode.NotFound` first, then call `response.EnsureSuccessStatusCode()` for everything else.
- **`LowStockAsync`** calls your own `GetAllAsync(null)`, then LINQ. `p.UnitsInStock ?? 0` counts a missing stock figure as 0.

## When you're done

Every test passes, and with the API running, the program prints:

```text
Beverages:
  Chai $18.00
  Chang $19.00
  Chartreuse verte $18.00
  Côte de Blaye $263.50
  Guaraná Fantástica $4.50
  Ipoh Coffee $46.00
  Lakkalikööri $18.00
  Laughing Lumberjack Lager $14.00
  Outback Lager $15.00
  Rhönbräu Klosterbier $7.75
  Sasquatch Ale $14.00
  Steeleye Stout $18.00
Running low (fewer than 5 in stock):
  Alice Mutton: 0
  Chef Anton's Gumbo Mix: 0
  Gorgonzola Telino: 0
  Perth Pasties: 0
  Thüringer Rostbratwurst: 0
  Sir Rodney's Scones: 3
  Longlife Tofu: 4
  Louisiana Hot Spiced Okra: 4
There's no product 999
```

Stop the API and run the program again: it says the API had a problem, instead of crashing.

## Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

1. On GitHub, click **+**, then **New repository**. Name it (for example `exercise-an-api-client`), choose **Public**, and click **Create repository**. Leave out the README: your folder already has one.
2. In a terminal in your exercise folder (Git Bash on Windows), send your work to your new repo. If you downloaded the ZIP:

   ```bash
   git init -b main
   git add .
   git commit -m "My solution"
   git remote add origin https://github.com/your-name/exercise-an-api-client.git
   git push -u origin main
   ```

   If you cloned the starter instead, point your copy at your own repo, then commit and push:

   ```bash
   git remote set-url origin https://github.com/your-name/exercise-an-api-client.git
   git add .
   git commit -m "My solution"
   git push -u origin main
   ```

3. Paste your repo's address, such as `https://github.com/your-name/exercise-an-api-client`, into **Submit your exercise** on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

## So what

Two programs, talking over HTTP: the API you built, and a client that uses it like a set of ordinary methods. That's how most modern software fits together, from phone apps to the services behind big websites.

## Key terms

- [API Client](https://www.ask-codey.com/glossary/api-client)
- [HttpClient](https://www.ask-codey.com/glossary/httpclient-c-sharp)
- [JSON Serialization](https://www.ask-codey.com/glossary/json-serialization)
- [Async/Await](https://www.ask-codey.com/glossary/async-await)

## Related

- [A Simple API Client](https://www.ask-codey.com/lessons/calling-apis-with-httpclient-using-a-simple-http-client)
- [Exercise: Northwind Web API](https://www.ask-codey.com/lessons/exercise-northwind-web-api)

Source: https://www.ask-codey.com/lessons/exercise-an-api-client
