2
0
Simon Dellenbach cf91281a51 Initial exercise setup.
Additions

* Instructions for manually starting the database.
* Each phase now has a success criteria with how to verify.
* Troubleshooting section for working with the Docker DB container.
* All phases of the exercise are described in README.md (with as little advanced hints as possible).
* DFD to illustrate phase 1
* Debugging starts the database container and applies schema migrations (no setup required).
* Launch settings for VS Code, VS 2022 and Rider (IntelliJ IDEA).
* Swagger UI is available at <http://localhost:8080/swagger/index.html> for testing.
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00
2025-07-24 17:10:10 +02:00

dotnet-interview-exercise

This exercise is designed to test your skills in C# and .NET.

Technologies used in this exercise

  • .NET 8.0 / C#
  • Minimal ASP.NET Core Web API
  • Entity Framework Core
  • PostgreSQL Database (Docker)
  • HttpClient for downstream REST API calls
  • ???

Prerequisites

  • Latest .NET 8 SDK
  • Visual Studio Code
  • Docker Desktop and docker compose plugin
  • Disable Copilot completions (that would make it too easy...)
  • Be ready for sharing your screen in Zoom
  • Launch settings have been configured to run and debug the web application

Exercise

Phase 1

Note: For all API and schemas, see https://jsonplaceholder.typicode.com/.

  • Implement the missing code in JsonPlaceholderClient
    • Setup of the client.
    • Method for fetching one post from the external API at https://jsonplaceholder.typicode.com/posts/{id}.
  • In our endpoint handler, fetch the post with the ID provided.
  • Store the post received in the database using the Post entity, but leave out UpdatedAt for now.
  • Use http://localhost:8080/swagger/index.html for testing.
sequenceDiagram
    title Overview
    actor B as Swagger UI
    participant S as Service
    participant E as External Service
    participant D as Database
    B->>S: GetPostById
    S<<->>E: GetPostById
    S->>D: Store Post
    S->>B: Return Post

Success Criteria: Verify that the post has been saved with the database with:

$ docker compose exec --env PGPASSWORD=password db psql -h localhost -U user --db mydatabase -c "select * from posts;"

 id | user_id |                                   title                                    |                        body                         |       updated_at
----+---------+----------------------------------------------------------------------------+-----------------------------------------------------+------------------------
  1 |       1 | sunt aut facere repellat provident occaecati excepturi optio reprehenderit | quia et suscipit                                   +| 1970-01-01 00:00:00+00
    |         |                                                                            | suscipit recusandae consequuntur expedita et cum   +|
    |         |                                                                            | reprehenderit molestiae ut ut quas totam           +|
    |         |                                                                            | nostrum rerum est autem sunt rem eveniet architecto |
(1 row)

Phase 2

  • Check whether we already have the post in the database.
  • If we do, return the post from the database, but without the internal updated_at timestamp.
  • If we don't, fetch the post from the external API and store it in the database, and return it.
  • Success Criteria: Check the service logs to see if the post was read from the database, or whether the client made a call to the downstream service.

Phase 3

  • Set the UpdatedAt property of the Post entity to the current date and time when storing it in the database.
  • If the post in the database has been updated less than 1 minute ago, return the one from the database.
  • If the post in the database is older than 1 minute (extra short value for testing), fetch the post from the external API again and update it in the database before returning.
  • Success Criteria: Check the service logs to see if the post was read from the database, or whether the client made a call to the downstream service.

Phase 4

  • Think about how we could improve resiliency in downstream API calls.
  • For setup, pull in the changes from the phase4 branch.
    • It adds chaos-injecting code in Program.cs to simulate random failures in downstream API calls.
    • Execute a couple of requests with increasing ids until an error happens.
  • Implement resiliency measures to handle these kinds of failures.
  • Success Criteria: Check the service logs to see the resiliency measures in action.

Phase 5

  • Now increase the chaos outcomes rate of 503 to 95% to simulate a partial outage. What is the outcome on our endpoint?
  • Improve the error response returned by handling the downstream error accordingly.
  • Success Criteria: Service should return the appropriate error response that warrants retrying the call from the client side.

Bonus Phase 6 (discussion only)

  • The current DB schema solution has big drawbacks. What are they?
  • How would you implement schema migrations that avoid these issues?
  • What do you need to consider in the setup for proper schema migrations?

Bonus Phase 7 (discussion only)

  • Imagine the following deployment scenario:
    • The service is deployed to and running in the Elastic Container Service (ECS) in Amazon AWS
    • The downstream service requires authentication
  • How would you store and retrieve the required credentials?
  • What options do you see to also require authentication on our little service?

Troubleshooting

Start database manually

Open a terminal at the repo root and execute

$ docker compose up -d db

[+] Running 3/3
 ✔ Network dotnet-interview-exercise_default   Created  0.0s
 ✔ Volume "dotnet-interview-exercise_db_data"  Created  0.0s
 ✔ Container dotnet-interview-exercise-db-1    Started  0.1s

Cleanup database

In case something went wrong, wipe and rebuild the database

$ docker compose down -v

[+] Running 3/3
 ✔ Container dotnet-interview-exercise-db-1   Removed. 0.2s
 ✔ Network dotnet-interview-exercise_default  Removed. 0.2s
 ✔ Volume dotnet-interview-exercise_db_data   Removed. 0.0s

$ docker compose up -d db
[+] Running 3/3
 ✔ Network dotnet-interview-exercise_default   Created  0.0s
 ✔ Volume "dotnet-interview-exercise_db_data"  Created  0.0s
 ✔ Container dotnet-interview-exercise-db-1    Started  0.1s
Description
Base setup for an interview exercise using a .NET 8 service with a database backend.
Readme 71 KiB
Languages
C# 92.4%
Dockerfile 7.6%