Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Extending a Minimal API with CRUD Operations and Validation

Build a production-minded ASP.NET Core 10 minimal API by adding full CRUD endpoints, enforcing consistent typed responses, returning Problem Details-style errors, and implementing reusable validation with endpoint filters. You’ll finish by verifying correct behavior with an HTTP client workflow across create, read, update, and delete operations.

Lab platform
Lab Info
Level
Beginner
Last updated
May 15, 2026
Duration
40m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Step 1: Understand the baseline minimal API and the learning sequence

    In this lab you'll expand a minimal API from a small starting point into a consistent CRUD API.

    The starter files live in CourseCatalog.Api:

    • Program.cs — application bootstrap and (currently empty) endpoint mappings
    • Courses/Models.csCourse, CourseRequest, and CourseResponse records
    • Courses/InMemoryCourseRepository.cs — a thread-safe in-memory store you'll use through ICourseRepository
    • Validation/CourseRequestValidator.cs — a placeholder you'll fill in during Step 3
    • Validation/ValidateCourseRequestFilter.cs — an IEndpointFilter placeholder for Step 3

    A companion test project at CourseCatalog.Api.Tests will verify each task. You can run a single check at any time from the workspace directory with ./runTest.sh TestStep<N>Task<M>, or run them all with dotnet test CourseCatalog.Api.Tests.

    Why the order matters:

    • Route groups and typed results define a consistent HTTP surface area early.
    • Validation is easiest to apply once you know the shapes of requests and responses.
    • Endpoint filters are most valuable after multiple endpoints exist (so you can remove duplication).
    • Testing last gives you confidence the entire contract works together, and the HTTP client workflow mirrors real debugging.

    Get the project running once before you start: From CourseCatalog.Api, run dotnet run. The app should start and redirect / to Swagger UI. Stop it with Ctrl+C and you're ready to begin Step 2.

    info> If you get stuck on a task, you can find solution files with the completed code for each task in the solution folder of your filetree.

    This lab experience was developed by the Pluralsight team using an internally developed AI tool. All sections were verified by human experts for accuracy prior to publications. However, content may still contain errors or inaccuracies, and we recommend independent verification. To report a problem or provide feedback, click here. Feedback may be used to improve accuracy in accordance with our Privacy Policy.

  2. Challenge

    Step 2: Add read endpoints and organize routing with route groups

    Minimal APIs are great for small services, but they can become hard to maintain if endpoints are scattered. Route groups let you:

    • Keep related endpoints together
    • Apply shared filters and conventions
    • Create a consistent URL hierarchy

    Typed results (the TypedResults.* helpers and Results<TOk, TError> return type) help ensure your handlers return clear, consistent responses and give better OpenAPI metadata than returning arbitrary objects.

    A quick note about route patterns inside a group: when the group prefix is /api/courses, mapping a child pattern of "" (empty string) yields the route /api/courses, while mapping "/" yields /api/courses/ (with a trailing slash). Use "" for collection roots in this lab so requests like GET /api/courses match cleanly.

    All work in this step happens in CourseCatalog.Api/Program.cs.

  3. Challenge

    Step 3: Implement validation with parameter binding and endpoint filters

    Minimal APIs support binding route parameters and request bodies directly in handler parameters. Validation can be done inline, but endpoint filters (IEndpointFilter) let you:

    • Centralize request validation in one place
    • Keep handlers focused on business logic
    • Standardize error responses (especially validation problems via TypedResults.ValidationProblem(...))

    A Problem Details-style validation response (RFC 9457) gives clients a predictable structure to display or log field-level issues.

    In this step you'll implement the validator class, the endpoint filter, and add the first write endpoint (POST /api/courses) so the filter has something concrete to guard. You'll then refactor by lifting the filter from a single endpoint up to the route group itself—setting up Step 4 for free.

    Files you'll touch:

    • CourseCatalog.Api/Validation/CourseRequestValidator.cs
    • CourseCatalog.Api/Validation/ValidateCourseRequestFilter.cs
    • CourseCatalog.Api/Program.cs
  4. Challenge

    Step 4: Finish the write surface with consistent typed results

    CRUD endpoints should communicate clearly through status codes:

    • POST create: typically 201 Created with a Location header
    • PUT update: often 204 No Content (or 200 OK with the updated representation)
    • DELETE: commonly 204 No Content on success

    For failures, Problem Details-style errors (TypedResults.Problem(...)) keep response formats consistent and client-friendly.

    In this step you'll upgrade the basic POST you wired up in Step 3 to return a proper 201 Created with a Location header, then add PUT and DELETE to round out the CRUD surface. The validation filter you applied at the route-group level in Task 3.3 will automatically protect every new write endpoint—no extra wiring needed.

    All work in this step happens in workspace/CourseCatalog.Api/Program.cs.

  5. Challenge

    Step 5: Verify behavior using an HTTP client workflow and integration tests

    Automated tests ensure you don't regress behavior. A simple HTTP client workflow file is also valuable because:

    • It documents common scenarios
    • It's easy to run during debugging
    • It mirrors how consumers call the API

    In this step you'll add both: a human-readable request sequence in workspace/CourseCatalog.Api/CourseCatalog.http and an automated integration test in workspace/CourseCatalog.Api.Tests/Step5Tests.cs that validates the full CRUD lifecycle through the in-memory WebApplicationFactory<Program>.

  6. Challenge

    Step 6: Wrap up and recap

    Congratulations—you've turned a near-empty minimal API into a small but production-minded Course Catalog service.

    Along the way you:

    • Used app.MapGroup(...) to organize related endpoints under /api/courses and apply shared conventions like tags and filters in one place.
    • Returned consistent, OpenAPI-friendly responses with TypedResults (Ok, CreatedAtRoute, NoContent, Problem, ValidationProblem) and the Results<T1, T2, ...> union type.
    • Encapsulated request validation in CourseRequestValidator and reused it through an IEndpointFilter (ValidateCourseRequestFilter) attached at the route-group level, so every write endpoint validates input the same way.
    • Implemented the full CRUD surface—GET, POST, PUT, DELETE—with thoughtful HTTP semantics (201 Created + Location, 204 No Content, 404 Problem Details).
    • Verified your work two ways: a CourseCatalog.http workflow file you can hand to a teammate or run yourself, and an integration test built on WebApplicationFactory<Program> that exercises the entire lifecycle.

    A few directions to take this further on your own:

    • Swap the InMemoryCourseRepository for an EF Core-backed implementation behind the same ICourseRepository interface—the endpoints shouldn't have to change.
    • Add authentication and authorization, then move those concerns onto the courses route group via .RequireAuthorization(...) so they apply consistently.
    • Introduce paging and filtering on GET /api/courses and surface the parameters through OpenAPI.
    • Add a global exception handler with app.UseExceptionHandler(...) that renders Problem Details for unhandled errors.

    Nice work—you've now got a solid template you can carry into real ASP.NET Core minimal API services.

About the author

Pluralsight’s AI authoring technology is designed to accelerate the creation of hands-on, technical learning experiences. Serving as a first-pass content generator, it produces structured lab drafts aligned to learning objectives defined by Pluralsight’s Curriculum team. Each lab is then enhanced by our Content team, who configure the environments, refine instructions, and conduct rigorous technical and quality reviews. The result is a collaboration between artificial intelligence and human expertise, where AI supports scale and efficiency, and Pluralsight experts ensure accuracy, relevance, and instructional quality, helping learners build practical skills with confidence.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight