API Development Tools — Postman, Insomnia, cURL & More
In this tutorial, you'll learn about API Development Tools. We cover key concepts, practical examples, and best practices.
API development tools let you design, test, debug, and document REST and GraphQL APIs without writing boilerplate client code — catching errors before integration.
What You'll Learn
In this tutorial, you'll learn Postman collections, environments, pre-request scripts, and test assertions; Insomnia's design mode for API-first development; cURL advanced flags for scripting; HTTPie, Bruno, and REST Client for VS Code; and automated API testing in CI/CD pipelines.
Why It Matters
APIs are the backbone of modern applications. A single malformed request can cause hours of debugging. Dedicated API tools let you craft requests precisely, inspect responses, automate test suites, and share API documentation with your team.
Real-World Use
Doda Browser's extension API is documented as a Postman collection with environment variables for development, staging, and production. The same collection runs as automated tests in the CI pipeline, ensuring backward compatibility with every release.
flowchart LR A[API Design] --> B[Insomnia / OpenAPI] B --> C[Development] C --> D[Postman / Bruno] D --> E[Testing] E --> F[CI/CD Automation] E --> G[cURL / HTTPie] F --> H[Newman / Postman CLI]
Postman — Collections and Environments
Collection with Dynamic Variables
{
"info": {
"name": "Security Scanner API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Scan File",
"event": [
{
"listen": "prerequest",
"script": {
"exec": [
"// Generate a unique filename for each test run",
"pm.variables.set('filename', 'test_' + Date.now() + '.exe');]
]
}
}
],
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{api_key}}" },
{ "key": "Content-Type", "value": "application/json" }
],
"body": {
"mode": "raw",
"raw": "{\"filename\": \"{{filename}}\", \"scan_type\": \"deep\"}"
},
"url": {
"raw": "{{base_url}}/v1/scan",
"host": ["{{base_url}}"],
"path": ["v1", "scan"]
}
}
}
]
}
Expected behavior: The pre-request script generates a unique filename. The {{api_key}} and {{base_url}} variables are resolved from the active environment. The request sends a POST with the dynamic payload.
Test Scripts
// Postman Tests tab — runs after the response arrives
pm.test("Status code is 200", () => {
pm.response.to.have.status(200);
});
pm.test("Response has scan_id", () => {
const jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("scan_id");
pm.expect(jsonData.scan_id).to.match(/^scan_[a-z0-9]{24}$/);
});
pm.test("Response time is acceptable", () => {
pm.expect(pm.response.responseTime).to.be.below(5000);
});
Expected behavior: After each request, Postman evaluates the test scripts. A green checkmark appears for passed tests, red for failures. The collection runner shows a summary of all test results.
Insomnia — API Design Mode
Insomnia's Design Mode lets you edit OpenAPI specs visually and generate requests from the spec.
openapi: 3.1.0
info:
title: Security Scanner API
version: 1.0.0
paths:
/v1/scan:
post:
summary: Submit a file for scanning
requestBody:
content:
application/json:
schema:
type: object
properties:
filename:
type: string
scan_type:
type: string
enum: [quick, deep, heuristic]
responses:
'202':
description: Scan accepted
content:
application/json:
schema:
type: object
properties:
scan_id:
type: string
status:
type: string
Expected behavior: Insomnia generates a request from the OpenAPI spec. Any change to the spec updates the request. You can also auto-generate client SDKs from the spec.
cURL — Command-Line Power
Advanced cURL Flags
# POST with JSON body and auth header
curl -X POST https://api.example.com/v1/scan \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename": "test.exe", "scan_type": "deep"}' \
-w "\nHTTP Code: %{http_code}\nTime: %{time_total}s\n"
# Follow redirects and save cookies
curl -L -c cookies.txt -b cookies.txt https://example.com/login \
-d "username=admin&password=secret"
# Upload a file via multipart/form-data
curl -F "file=@malware-sample.exe" \
-F "scan_type=deep" \
-H "Authorization: Bearer $API_KEY" \
https://api.example.com/v1/upload
Expected output: The first command shows the response body followed by HTTP Code: 202 and Time: 1.234s. The second follows redirects and persists cookies. The third uploads a binary file.
cURL Scripting
#!/bin/bash
# Script: api-test.sh — Test the scan endpoint
BASE_URL="https://api.example.com"
API_KEY="sk-test-key"
test_scan() {
local filename="$1"
local response=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "$BASE_URL/v1/scan" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"filename\": \"$filename\", \"scan_type\": \"quick\"}")
echo "$filename -> HTTP $response"
}
test_scan "clean.pdf"
test_scan "malware.exe"
test_scan "script.js"
Expected output: Each test prints the filename and HTTP status code. This pattern is used for smoke tests in CI pipelines.
API Tool Comparison
| Tool | Interface | Best For | Automation |
|---|---|---|---|
| Postman | GUI + CLI | Full lifecycle: design, test, document, monitor | Newman / Postman CLI |
| Insomnia | GUI | API-first development with OpenAPI specs | Inso CLI |
| cURL | CLI | Scripting, CI/CD, simple requests | Shell scripts |
| HTTPie | CLI | Readable output, human-friendly syntax | Shell scripts |
| REST Client (VS Code) | In-editor | Quick testing without leaving VS Code | .http files in repo |
Common Errors
- Not using environment variables for URLs — Hardcoding
localhost:3000means changing every request when switching to staging. Use{{base_url}}variables and switch environments. - Test failures due to missing auth tokens — Pre-request scripts should check for token expiry and refresh automatically. Store tokens as collection variables that persist across requests.
- Expecting exact response ordering in assertions — JSON object key order is not guaranteed. Use
pm.expect(data).to.have.property("id")instead of index-based access. - cURL not following redirects — By default, cURL does not follow redirects. Use
-Lto follow, and combine with-bfor cookie handling. - Forgetting Content-Type header — POST/PUT requests without
Content-Type: application/jsonare often interpreted as form-encoded, causing the server to reject them.
Practice Questions
What is the advantage of Postman environments over hardcoded variables? Environments let you switch between dev, staging, and production with one click. Variables like
{{base_url}}and{{api_key}}resolve from the active environment.How do you automate Postman collections in CI/CD? Export the collection and environment as JSON files, then use
newman run collection.json -e environment.jsonin your CI pipeline.What is the difference between
curlandhttpiefor command-line API testing? HTTPie has a simpler syntax (http POST url key=value), colored JSON output, and sensible defaults. cURL is more widely available and supports more protocols.How do you chain API requests in Postman (using response from one as input to another)? Use
pm.variables.set()in the Tests tab of the first request to store a response value as a collection variable, then use{{variable}}in the second request.
Challenge
Create a Postman collection that tests a complete user authentication flow: register, login (get JWT token), access a protected resource, refresh the token, and logout. Include pre-request scripts for token management and test assertions for each response.
Mini Project: API Test Suite for a File Scanning Service
Build a Postman collection for a file scanning API:
- Create an environment with
base_url,api_key, andscan_idvariables - Add a request to submit a file for scanning (POST /v1/scan)
- Add a request to check scan status (GET /v1/scan/{{scan_id}})
- Add a request to get scan results (GET /v1/scan/{{scan_id}}/results)
- Write test scripts: 200 status, valid scan_id pattern, status transitions (queued -> scanning -> completed)
- Use a pre-request script to generate a unique filename
- Export the collection and run it with
newmanfrom the command line
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro