TL;DR:
.httpand.restfiles are plain-text API request files supported natively by JetBrains IDEs and via the REST Client extension in VS Code- They live in your repository, work in version control, and don’t require a separate application to run
- Best for teams who want API requests alongside the code that makes them — not a full replacement for Postman when you need complex test environments, mocking, or team sharing features
The API client category has become crowded. Postman, Bruno, Insomnia, HTTPie, Thunder Client — there’s no shortage of tools for making HTTP requests. But there’s another option that many developers overlook: the .http file format, supported natively in JetBrains IDEs and via a VS Code extension, that lets you write and run API requests as plain text files that live in your project.
No GUI required. No separate application. No syncing to a cloud account. Just a text file with your requests in it, next to the code that implements them.
What an HTTP File Looks Like
The format is straightforward. Comments start with # or //. Requests are separated by ###. Variables are referenced with {{variableName}}.
### Get all users
GET https://api.example.com/users
Authorization: Bearer {{auth_token}}
Content-Type: application/json
### Create a user
POST https://api.example.com/users
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"name": "Jane Smith",
"email": "jane@example.com",
"role": "editor"
}
### Update user (replace {{user_id}} with actual ID)
PUT https://api.example.com/users/{{user_id}}
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"role": "admin"
}
### Delete user
DELETE https://api.example.com/users/{{user_id}}
Authorization: Bearer {{auth_token}}
In JetBrains (IntelliJ IDEA, WebStorm, PyCharm, etc.), every request gets a “Run” gutter icon. Click it and the response opens inline. In VS Code with the REST Client extension by Huachao Mao, you click “Send Request” above each block.
Variables and Environments
Variables let you switch between development, staging, and production environments without editing request files. In VS Code REST Client, define variables in a http-client.env.json file:
{
"dev": {
"base_url": "http://localhost:3000",
"auth_token": "dev_token_abc123"
},
"staging": {
"base_url": "https://staging.api.example.com",
"auth_token": "{{$env AUTH_TOKEN_STAGING}}"
},
"production": {
"base_url": "https://api.example.com",
"auth_token": "{{$env AUTH_TOKEN_PROD}}"
}
}
Switch environments in VS Code via the status bar or command palette. Reference environment variables (from .env files or OS environment) with {{$env VARIABLE_NAME}} — keep tokens out of the file and the repository.
JetBrains uses a similar approach with http-client.env.json (public variables) and http-client.private.env.json (gitignored, for secrets).
Response Handling and Chaining
The REST Client extension supports response handlers — JavaScript scripts that run after a request and can store values for use in subsequent requests:
### Login and capture token
POST https://api.example.com/auth/login
Content-Type: application/json
{
"email": "test@example.com",
"password": "{{password}}"
}
> {%
client.test("Login successful", function() {
client.assert(response.status === 200, "Status was not 200");
});
client.global.set("auth_token", response.body.token);
%}
### Use the captured token in the next request
GET https://api.example.com/profile
Authorization: Bearer {{auth_token}}
This covers the most common chaining pattern: authenticate, capture the token, use it in subsequent requests. JetBrains has similar scripting support with a client object for assertions and variable setting.
Multipart and File Upload
### Upload a file
POST https://api.example.com/uploads
Authorization: Bearer {{auth_token}}
Content-Type: multipart/form-data; boundary=WebKitFormBoundary
--WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="data.csv"
Content-Type: text/csv
< ./fixtures/sample-data.csv
--WebKitFormBoundary--
The < operator reads file contents from disk. Both VS Code REST Client and JetBrains support this.
GraphQL
### GraphQL query
POST https://api.example.com/graphql
Content-Type: application/json
Authorization: Bearer {{auth_token}}
{
"query": "query GetUser($id: ID!) { user(id: $id) { name email role } }",
"variables": {
"id": "{{user_id}}"
}
}
Where HTTP Files Win
Version control: The requests live in the repository. New team members clone the project and have all the API calls they need immediately. No importing collections, no shared workspaces to configure.
Code-adjacent documentation: A requests.http file in the same directory as your route handlers is genuinely useful documentation. It shows exactly how the API is meant to be called, with real examples.
No account required: Postman’s free tier pushes you toward a cloud account. HTTP files have no account, no sync, no vendor dependency.
Simplicity: If your requirements are “I want to make HTTP requests and see the response”, .http files are faster to set up than any dedicated tool.
Where They Fall Short
Test suites: Postman and Bruno have better support for structured test suites with assertions, test runners, and CI integration. VS Code REST Client’s client.test() is functional but limited compared to Postman’s test framework.
Mocking: If you need to mock API responses for testing, HTTP files don’t help. That’s a separate tool category (WireMock, MSW, Prism).
Non-technical collaborators: HTTP files require text editing. If your QA team or product managers want to run API calls from a GUI, Postman or Insomnia are better options.
Collections with rich metadata: Postman collections have descriptions, example responses, and documentation features built in. An .http file is just requests and comments.
The practical guideline: use HTTP files for your own development workflow and as team-accessible documentation in the repository. Keep Postman or Bruno for complex integration tests, mock servers, and when you’re working with non-developer collaborators. They’re complementary, not competing.