Generate .http files from OpenAPI specifications
.http files were made popular by the Visual Studio Code extension REST Client, which then was adopted by JetBrains IDE's, and later on Visual Studio 2022
HTTP File Generator now ships as a Rust CLI plus thin IDE hosts.
- crates.io:
cargo install httpgenerator- Best when you already have Rust and Cargo (Rust 1.95+) on your machine and want the canonical Rust ecosystem install path for published releases.
- The public crates.io surface is the end-user CLI crate
httpgeneratorplus the reusable library cratehttpgenerator-core.
- One-line installer (macOS/Linux):
curl -fsSL https://christianhelle.com/httpgenerator/install | bash- Best when you want the prebuilt CLI without installing the Rust toolchain.
- Use
curl -fsSL https://christianhelle.com/httpgenerator/install | INSTALL_DIR=$HOME/.local/bin bashto install into a user-writable directory, or pass--version <tag>to pin a specific release.
- One-line installer (Windows PowerShell):
irm https://christianhelle.com/httpgenerator/install.ps1 | iex- Use
-InstallDir <path>to choose a custom directory or-Version <tag>to pin a specific release.
- Use
- Standalone CLI archives: download the platform-specific archive from GitHub Releases and place
httpgenerator/httpgenerator.exeonPATH.httpgenerator-<version>-linux-x64.tar.gzhttpgenerator-<version>-darwin-x64.tar.gzhttpgenerator-<version>-darwin-arm64.tar.gzhttpgenerator-<version>-win-x64.zip
- Build locally:
cargo build --release -p httpgenerator - Workspace testing:
cargo test --workspace - VS Code: install the platform-specific
.vsixfor your OS and architecture. Each package bundles the native Rust CLI, and you can override it withhttp-file-generator.executablePath. - Visual Studio 2022: install the Visual Studio
.vsix, which bundleshttpgenerator.exe.
The legacy .NET CLI remains in the repository as the migration oracle and compatibility host, but it is no longer the primary release path.
crates.io complements rather than replaces the existing release channels. Use crates.io for Rust-native installation and library consumption, use the install scripts or GitHub Releases for prebuilt standalone CLI binaries, and use the VS Code / Visual Studio Marketplace packages when you want the editor hosts with their bundled binaries.
The standalone release matrix currently covers Linux x64, macOS x64, macOS ARM64, and Windows x64. Windows on ARM currently uses the x64 standalone install path.
src\rustcontains the two Rust workspace projects:src/rust/clifor thehttpgeneratorCLI package andsrc/rust/corefor thehttpgenerator-corelibrary package.src\dotnetcontains the legacy .NET CLI, core library, test suite, and Visual Studio VSIX host.src\vscodecontains the VS Code extension.- Root-level entrypoints are preserved: run Cargo commands from the repository root via
Cargo.toml, target the moved .NET solutions withsrc/dotnet/*.slnx, and invoke VS Code packaging withsrc\vscode\build.ps1. - Plain
cargo publish --dry-run --allow-dirtyfrom the repo root attempts both Rust packages:httpgenerator-coreandhttpgenerator. CI still checks publish readiness in dependency order withcargo publish --dry-run -p httpgenerator-corepluscargo check -p httpgenerator.
httpgeneratoris the public CLI crate and the package normal users install withcargo install httpgenerator.httpgenerator-coreis the public library crate for the normalized model,.httprendering pipeline, and thehttpgenerator_core::openapi::*loading/inspection/normalization API.- Differential compatibility coverage remains in the repository as test-only support under
src/rust/cli/tests.
USAGE:
httpgenerator [URL or input file] [OPTIONS]
EXAMPLES:
httpgenerator ./openapi.json
httpgenerator ./openapi.json --output ./
httpgenerator ./openapi.json --output-type onefile
httpgenerator https://petstore.swagger.io/v2/swagger.json
httpgenerator https://petstore3.swagger.io/api/v3/openapi.json --base-url https://petstore3.swagger.io
httpgenerator ./openapi.json --authorization-header Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9c
httpgenerator ./openapi.json --azure-scope [Some Application ID URI]/.default
httpgenerator ./openapi.json --generate-intellij-tests
httpgenerator ./openapi.json --custom-header X-Custom-Header: Value --custom-header X-Another-Header: AnotherValue
ARGUMENTS:
[URL or input file] URL or file path to OpenAPI Specification file
OPTIONS:
DEFAULT
-h, --help Prints help information
-v, --version Prints version information
-o, --output <OUTPUT> ./ Output directory
--no-logging Don't log errors or collect telemetry
--skip-validation Skip validation of OpenAPI Specification file
--authorization-header <HEADER> Authorization header to use for all requests
--load-authorization-header-from-environment Load the authorization header from an environment variable or define it in the
.http file. You can use --authorization-header-variable-name to specify the
environment variable name
--authorization-header-variable-name <VARIABLE-NAME> authorization Name of the environment variable to load the authorization header from
--content-type <CONTENT-TYPE> application/json Default Content-Type header to use for all requests
--base-url <BASE-URL> Default Base URL to use for all requests. Use this if the OpenAPI spec doesn't
explicitly specify a server URL
--output-type <OUTPUT-TYPE> OneRequestPerFile OneRequestPerFile generates one .http file per request. OneFile generates a
single .http file for all requests. OneFilePerTag generates one .http file per
first tag associated with each request
--azure-scope <SCOPE> Azure Entra ID Scope to use for retrieving Access Token for Authorization header
--azure-tenant-id <TENANT-ID> Azure Entra ID Tenant ID to use for retrieving Access Token for Authorization
header
--timeout <SECONDS> 120 Timeout (in seconds) for writing files to disk
--generate-intellij-tests Generate IntelliJ tests that assert whether the response status code is 200
--custom-header Add custom HTTP headers to the generated request
--skip-headers Don't generate header parameters in the files
Running the following:
httpgenerator https://petstore.swagger.io/v2/swagger.jsonOutputs the following:
Which will produce the following files:
-rw-r--r-- 1 christian 197121 593 Dec 10 10:44 DeleteOrder.http
-rw-r--r-- 1 christian 197121 231 Dec 10 10:44 DeletePet.http
-rw-r--r-- 1 christian 197121 358 Dec 10 10:44 DeleteUser.http
-rw-r--r-- 1 christian 197121 432 Dec 10 10:44 GetFindPetsByStatus.http
-rw-r--r-- 1 christian 197121 504 Dec 10 10:44 GetFindPetsByTags.http
-rw-r--r-- 1 christian 197121 371 Dec 10 10:44 GetInventory.http
-rw-r--r-- 1 christian 197121 247 Dec 10 10:44 GetLoginUser.http
-rw-r--r-- 1 christian 197121 291 Dec 10 10:44 GetLogoutUser.http
-rw-r--r-- 1 christian 197121 540 Dec 10 10:44 GetOrderById.http
-rw-r--r-- 1 christian 197121 275 Dec 10 10:44 GetPetById.http
-rw-r--r-- 1 christian 197121 245 Dec 10 10:44 GetUserByName.http
-rw-r--r-- 1 christian 197121 513 Dec 10 10:44 PostAddPet.http
-rw-r--r-- 1 christian 197121 521 Dec 10 10:44 PostCreateUser.http
-rw-r--r-- 1 christian 197121 610 Dec 10 10:44 PostCreateUsersWithListInput.http
-rw-r--r-- 1 christian 197121 464 Dec 10 10:44 PostPlaceOrder.http
-rw-r--r-- 1 christian 197121 299 Dec 10 10:44 PostUpdatePetWithForm.http
-rw-r--r-- 1 christian 197121 274 Dec 10 10:44 PostUploadFile.http
-rw-r--r-- 1 christian 197121 513 Dec 10 10:44 PutUpdatePet.http
-rw-r--r-- 1 christian 197121 541 Dec 10 10:44 PutUpdateUser.httpIn this example, the contents of PostAddPet.http looks like this:
@contentType = application/json
#############################################
### Request: POST /pet
### Summary: Add a new pet to the store
### Description: Add a new pet to the store
#############################################
POST https://petstore3.swagger.io/api/v3/pet
Content-Type: {{contentType}}
{
"id": 0,
"name": "name",
"category": {
"id": 0,
"name": "name"
},
"photoUrls": [
""
],
"tags": [
{
"id": 0,
"name": "name"
}
],
"status": "available"
}and the contents of GetPetById.http looks like this:
@contentType = application/json
#######################################
### Request: GET /pet/{petId}
### Summary: Find pet by ID
### Description: Returns a single pet
#######################################
### Path Parameter: ID of pet to return
@petId = 0
GET https://petstore3.swagger.io/api/v3/pet/{{petId}}
Content-Type: {{contentType}}with the --generate-intellij-tests option, the output looks like this:
@contentType = application/json
#######################################
### Request: GET /pet/{petId}
### Summary: Find pet by ID
### Description: Returns a single pet
#######################################
### Path Parameter: ID of pet to return
@petId = 1
GET https://petstore3.swagger.io/api/v3/pet/{{petId}}
Content-Type: {{contentType}}
> {%
client.test("Request executed successfully", function() {
client.assert(
response.status === 200,
"Response status is not 200");
});
%}Here's an advanced example of generating .http files for a REST API hosted on Microsoft Azure that uses the Microsoft Entra ID service as an STS. For this example, I use PowerShell and Azure CLI to retrieve an access token for the user I'm currently logged in with.
az account get-access-token --scope [Some Application ID URI]/.default `
| ConvertFrom-Json `
| %{
httpgenerator `
https://api.example.com/swagger/v1/swagger.json `
--authorization-header ("Bearer " + $_.accessToken) `
--base-url https://api.example.com `
--output ./HttpFiles
}You can also use --azure-scope and --azure-tenant-id to let the Rust CLI acquire an access token during generation. The CLI currently checks Azure CLI and Azure Developer CLI logins and keeps generation running even if token acquisition fails.
httpgenerator `
https://api.example.com/swagger/v1/swagger.json `
--azure-scope [Some Application ID URI]/.default `
--base-url https://api.example.com `
--output ./HttpFilesThe Rust CLI keeps a sink-agnostic telemetry recorder that can capture feature usage and redacted error context.
By default, logging is enabled, but --no-logging disables feature and error event recording entirely.
User tracking is anonymous and derived from the Support key shown when running the tool while logging is enabled.
HTTP File Generator v0.1.5
Support key: mbmbqvdThe support key is just the first 7 characters of the generated anonymous identity. Authorization headers are recorded as [REDACTED], and personal machine details are normalized before telemetry is emitted.
No support key is generated when you opt out with --no-logging.
The VS Code extension is now packaged per platform because it bundles the native Rust CLI.
When http-file-generator.executablePath is empty, the extension looks for a bundled binary, repo-root workspace target\debug / target\release outputs, and finally httpgenerator on PATH. That means a Cargo-installed httpgenerator binary can also satisfy the extension if you prefer to manage the CLI yourself.
This tool is also available as a Visual Studio 2022 extension
From the Tools menu select Generate .http files
This opens the main dialog which has similar input fields as the CLI tool and now shells out to the Rust httpgenerator executable.
The Visual Studio extension resolves httpgenerator.exe from HTTPGENERATOR_PATH, the bundled VSIX payload, repo-root workspace target\debug / target\release outputs during development, or PATH. A Cargo-installed CLI can therefore be reused here as long as the binary is discoverable on PATH or via HTTPGENERATOR_PATH.
You can supply Azure Entra ID tenant and scope settings by clicking on the ... button beside the Authorization Headers input field. The Rust CLI acquires the access token during generation.
By default, the Output folder is pre-filled with the path of the currently active C# Project in the Solution Explorer, suffixed with \HttpFiles
Once the .http files are generated you can easily open and inspect them
For tips and tricks on software development, check out my blog
If you find this useful and feel a bit generous then feel free to buy me a coffee ☕





