👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Testing ASP.NET Web API with HTTP REPL and HTTP Files

Testing ASP.NET Web API with HTTP REPL and HTTP Files

Author - Abdul Rahman (Bhai)

Web API

29 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

Before deploying an API to production, you need to confirm it behaves correctly under a wide range of inputs — valid requests, missing fields, malformed bodies, and authenticated versus unauthenticated calls. Manual API testing is your first line of defence. In this article, we'll explore the full toolkit: HTTP REPL, .http files in Visual Studio, and the Endpoints Explorer — all demonstrated against the ILoveDotNet Articles API.

Why we gonna do?

A deployed API accepts any input a client chooses to send — invalid data, unexpected headers, or requests without authentication. Before your API reaches a consumer you need to verify:

  • Does it return the right HTTP status codes?
  • Does it expose implementation details in error responses?
  • Do authorization rules block the right users?
  • Does it return the correct data?

Several tools exist for this. Here is a quick overview:


┌────────────────────┬───────────────────────────────────────────────────────────┐
│ Tool               │ Best for                                                  │
├────────────────────┼───────────────────────────────────────────────────────────┤
│ Scalar UI          │ Quick interactive testing, especially with JWT auth       │
│ Postman / Insomnia │ Collections, scripted test suites, CI integration         │
│ Fiddler / SOAP UI  │ Low-level traffic inspection, REST and SOAP               │
│ HTTP REPL          │ CLI navigation of OpenAPI-described APIs                  │
│ .http files        │ Version-controlled request files inside Visual Studio     │
│ Endpoints Explorer │ Generating .http snippets from existing controller routes │
└────────────────────┴───────────────────────────────────────────────────────────┘
            

HTTP REPL and .http files are first-party Microsoft tools that live inside the developer's normal workflow — no extra applications to install or switch to.

How we gonna do?

Part 1: HTTP REPL — A CLI for Your API

HTTP REPL (HTTP Read-Eval-Print Loop) is a command-line tool that lets you navigate an API like a filesystem — you cd into endpoints the same way you navigate directories. It parses your OpenAPI spec automatically, so it knows which routes and parameters exist.

Step 1: Install HTTP REPL


dotnet tool install --global Microsoft.dotnet-httprepl
            

Step 2: Set OpenAPI Version to 3.0 for HTTP REPL Compatibility

At the time of writing, HTTP REPL cannot parse OpenAPI 3.1 (the default generated by Microsoft.AspNetCore.OpenApi in .NET 10). Force the spec to version 3.0 in your Program.cs:


using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi;

builder.Services.AddOpenApi("v1", options =>
{
    // Downgrade to 3.0 so the HTTP REPL can parse the spec
    options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0;
});

builder.Services.AddOpenApi("v2", options =>
{
    options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0;
});
            

Step 3: Navigate and Query with HTTP REPL

Start the REPL pointing at your running API and the location of the OpenAPI spec:


httprepl https://localhost:7001 --openapi https://localhost:7001/v1.json
            

Core navigation commands:


# List available endpoints at the current path
ls

# Navigate into a path segment (like cd in a terminal)
cd api
cd v1
cd articles

# Send a GET request to the current path
get

# Send a GET request requesting XML output
get -h "Accept:application/xml"

# Navigate to a specific resource
cd 1
get
            

When you navigate to the articles path and run ls, the REPL reads the OpenAPI spec to show you which HTTP verbs are available:


https://localhost:7001/api/v1/articles> ls

    GET
    POST

https://localhost:7001/api/v1/articles> get

HTTP/1.1 200 OK
Content-Type: application/json

[
  { "id": 1, "title": "Logging in ASP.NET Web API", "author": "Abdul Rahman", "channel": "WebAPI" },
  { "id": 2, "title": "JWT Auth in ASP.NET Web API",  "author": "Abdul Rahman", "channel": "WebAPI" }
]
            

Tip: keep route parameter names consistent across controllers. HTTP REPL builds its navigation map from the OpenAPI spec. If two controllers handling the same path segment use different parameter names — for example id in one endpoint and articleId in another — the REPL shows both as possible values when you run ls, which breaks navigation. The fix is to align parameter names across all handlers that share a route segment.

Step 4: POST with an Editor

For POST requests you need to provide a body. Configure a default editor first:


# Set your preferred editor (macOS example)
pref set editor.command.default "open -a 'TextEdit'"

# On Windows:
pref set editor.command.default "notepad"
            

Then run post. Your editor opens with a sample JSON body derived from the OpenAPI spec. Edit it, save, and close — the REPL sends the request:


post -h "Content-Type:application/json"
# Editor opens with sample body → edit → save → close

HTTP/1.1 201 Created
Location: /api/v1/articles/5
            

Step 5: Authenticated Requests with HTTP REPL

Disable auth temporarily to explore the API, then re-enable it. To send authenticated requests, first obtain a token from the login endpoint and set it as a global header:


# Navigate to the login endpoint (not in the OpenAPI spec — REPL can reach it anyway)
cd /api/auth/login
post -h "Content-Type:application/json"
# Editor opens → enter: { "userName": "author", "password": "Pa$$w0rd" }
# Copy the returned token

# Set the token as a global header for all subsequent requests
set header Authorization "Bearer eyJhbGciOiJI..."

# Now protected endpoints return 200
cd /api/v1/articles
get
# HTTP/1.1 200 OK
            

The set header command persists for the life of the REPL session — no need to pass the token on every individual command.

Part 2: .http Files — Test Requests in Your IDE

.http files let you define HTTP requests in a plain-text file that Visual Studio (and VS Code with the REST Client extension) can execute directly. They are version-controlled alongside your code, making them ideal for sharing test scenarios with the team.

Basic .http File Structure

@baseUrl = https://localhost:7001
@token   =

### Login and get a token
POST {{baseUrl}}/api/auth/login
Content-Type: application/json

{
  "userName": "author",
  "password": "Pa$$w0rd"
}

###

### Get all articles (authenticated)
GET {{baseUrl}}/api/v1/articles
Authorization: Bearer {{token}}

###

### Get a single article
GET {{baseUrl}}/api/v1/articles/1
Authorization: Bearer {{token}}
            

Named Requests and Response Chaining

One of the most useful .http file features is the ability to reference a previous response in a subsequent request. Name the login request with # @name, then access its JSON response body using JSON path notation:

@baseUrl = https://localhost:7001

### Login
# @name tokenRequest
POST {{baseUrl}}/api/auth/login
Content-Type: application/json

{
  "userName": "author",
  "password": "Pa$$w0rd"
}

###

### Get all articles — token extracted automatically from the login response
GET {{baseUrl}}/api/v1/articles
Authorization: Bearer {{tokenRequest.response.body.$.token}}
            

The $ represents the root of the JSON response body (JSON Path notation). $.token drills into the token property of the login response. You can also update the shared @token variable at the top:

@baseUrl = https://localhost:7001
@token   = {{tokenRequest.response.body.$.token}}

###
# @name tokenRequest
POST {{baseUrl}}/api/auth/login
Content-Type: application/json

{ "userName": "author", "password": "Pa$$w0rd" }

###

### All subsequent requests use the refreshed token automatically
GET {{baseUrl}}/api/v1/articles
Authorization: Bearer {{token}}

###

GET {{baseUrl}}/api/v2/articles
Authorization: Bearer {{token}}
            

Environment Files — Switching Between Dev and Production

Create an http-client.env.json file in the project root (or any parent folder) to define variable values per environment. Visual Studio displays a drop-down in the .http file editor to switch between them:


{
  "shared": {
    "contentType": "application/json"
  },
  "dev": {
    "baseUrl": "https://localhost:7001"
  },
  "staging": {
    "baseUrl": "https://api-staging.ilovedotnet.org"
  },
  "prd": {
    "baseUrl": "https://api.ilovedotnet.org"
  }
}
            

Variables defined in the shared key are available in all environments. Per-environment variables override shared ones when there is a conflict. With the dev environment selected, {{baseUrl}} resolves to https://localhost:7001 automatically.

Variable precedence: If you also declare @baseUrl directly inside the .http file, that declaration overrides the environment file. To let the environment file control the value, remove or comment out the in-file @baseUrl line — only then will switching environments in the drop-down take effect.

Part 3: Endpoints Explorer in Visual Studio

Endpoints Explorer is a Visual Studio tool window (View → Other Windows → Endpoints Explorer) that discovers all routes in your project and lists them with their HTTP method, route template, and controller/action. It is useful for two things:

  • Navigating large APIs. Click any endpoint to jump straight to the handler code.
  • Generating .http snippets. Right-click → Generate Request adds the request to your .http file as a starting point — saving you from typing route templates by hand.

Keep in mind that Endpoints Explorer is not perfect: it may generate requests for internal methods or miss constraints. Treat its output as a starting point, not a complete test suite. For large codebases, GitHub Copilot can generate .http file content from existing endpoints even more accurately.

Summary

  • Use Scalar UI for a polished interactive playground; use Postman/Insomnia for full test collections; use HTTP REPL when you prefer a CLI experience integrated with OpenAPI.
  • If HTTP REPL fails to parse your spec, set options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0 — HTTP REPL does not support OpenAPI 3.1 yet.
  • In HTTP REPL, navigate endpoints like a filesystem with ls and cd; use set header to set a global Bearer token once instead of per-request.
  • .http files live in source control alongside the code and support named requests and response chaining via JSON path notation (requestName.response.body.$.propertyName).
  • Use http-client.env.json to define environment-specific base URLs; the shared key contains variables available in all environments.
  • Endpoints Explorer in Visual Studio is a handy starting point for generating .http request stubs, though it is not always 100% accurate.
👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Web API
  • HTTP REPL
  • .http Files
  • Testing
  • Endpoints Explorer
  • Visual Studio
  • ASP.NET Core