curl vs restish: Why You Should Upgrade Your API Testing in 2025
curl has been the default for HTTP requests since forever. restish is what curl should've been for REST APIs in 2025.
We've been using curl to test APIs since the late 90s. It's fine. It works. But let's be honest: in 2025, typing out curl commands for REST APIs is like manually calculating your taxes with a pencil. Sure, you can do it, but why would you?
Enter restish. It's a modern CLI for REST APIs that actually understands REST semantics. Here's why you should probably switch.
The Problem With curl
curl is a general-purpose HTTP client. It doesn't know anything about REST APIs, JSON, or modern API conventions. This means you end up typing commands like:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGc..." \
-d '{"name": "John", "email": "john@example.com"}'Every. Single. Time.
You're manually specifying:
- The HTTP method
- Content type headers
- Authentication headers
- JSON data formatting
And if you want to see pretty output? Pipe it to jq. Want to save auth tokens? Write a wrapper script. Need to follow API links? Good luck.
What restish Actually Does
restish is designed specifically for REST APIs. It understands:
- JSON by default
- Authentication flows
- API specifications (OpenAPI, API Blueprint)
- HATEOAS and link following
- Response pagination
Same request in restish:
restish post api.example.com/users name=John email=john@example.comThat's it. No headers, no JSON formatting, no manual auth management. restish figures it out.
Authentication That Doesn't Suck
With curl, you manage tokens manually:
# Get a token
TOKEN=$(curl -X POST https://api.example.com/auth \
-d '{"username":"user","password":"pass"}' | jq -r .token)
# Use the token
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/usersWith restish, auth is configured once:
# Configure OAuth2 (one time setup)
restish api configure api.example.com \
--auth oauth-client-credentials \
--client-id YOUR_CLIENT_ID \
--client-secret YOUR_CLIENT_SECRET
# Now just make requests
restish get api.example.com/usersrestish handles token refresh, storage, and injection automatically. This alone is worth the switch.
JSON Handling Built-In
curl approach:
# Ugly unformatted JSON
curl https://api.example.com/users
# Pipe to jq for readability
curl -s https://api.example.com/users | jq
# Extract a field
curl -s https://api.example.com/users | jq -r '.[0].email'restish approach:
# Pretty JSON by default
restish get api.example.com/users
# Extract fields with built-in filtering
restish get api.example.com/users -f [0].email
# Output in different formats
restish get api.example.com/users -o yaml
restish get api.example.com/users -o csvNo external tools needed. It just works.
OpenAPI Integration
If your API has an OpenAPI spec (and in 2025, it should), restish can use it:
# Link an API spec
restish api configure api.example.com \
--spec-url https://api.example.com/openapi.json
# Now get autocomplete and validation
restish get api.example.com/users/[TAB]
# Shows available endpoints and parametersrestish validates your requests against the spec, shows available operations, and provides inline documentation. curl has no idea specs exist.
Real-World Example: Creating a User
The curl Way (2024 Style)
# Set up auth
export API_TOKEN="your_token_here"
export API_URL="https://api.example.com"
# Create a user
curl -X POST "$API_URL/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Accept: application/json" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com",
"role": "developer",
"metadata": {
"team": "backend",
"location": "remote"
}
}' | jq
# Get the user ID from output, then fetch details
USER_ID="abc123"
curl -X GET "$API_URL/users/$USER_ID" \
-H "Authorization: Bearer $API_TOKEN" | jq
# Update the user
curl -X PATCH "$API_URL/users/$USER_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
-d '{"role": "senior-developer"}' | jqThe restish Way (2025 Style)
# Create a user
restish post api.example.com/users \
name="Jane Doe" \
email=jane@example.com \
role=developer \
metadata.team=backend \
metadata.location=remote
# Get details (using response links)
restish links[self]
# Update the user
restish patch api.example.com/users/abc123 role=senior-developerLess typing, same result. Auth and formatting handled automatically.
Advanced Features That Actually Matter
1. Response Caching
# restish caches responses automatically
restish get api.example.com/users
# Fast on subsequent calls
# curl requires manual caching
curl -s https://api.example.com/users > users.json
cat users.json2. Link Following (HATEOAS)
# If API returns hypermedia links
restish get api.example.com/users
# Response includes: links.next = "/users?page=2"
# Follow links directly
restish links[next]
# curl requires manual URL construction
curl https://api.example.com/users?page=23. Request History
# restish keeps history
restish history
restish rerun 5 # Re-run command #5
# curl needs shell history hacks
history | grep curl4. API Profiles
# Switch between environments
restish api configure prod.example.com --auth ...
restish api configure staging.example.com --auth ...
# Switch contexts
restish get prod.example.com/users
restish get staging.example.com/users
# curl needs manual URL/token swappingWhen curl Is Still Better
Let's be fair. curl is more appropriate when:
You're not working with REST APIs: FTP, SMTP, file downloads, etc. restish is REST-only.
You need maximum control: curl exposes every HTTP detail. Sometimes you need that.
Scripting in constrained environments: curl is everywhere by default. restish needs installation.
Non-JSON APIs: If you're working with XML, form data, or binary protocols, curl is more flexible.
One-off requests: For a single quick request, curl -s url | jq is fine.
When restish Wins
Daily API development: If you're testing APIs regularly, restish saves hours of typing.
Authenticated APIs: OAuth2, API keys, token refresh—restish handles it all.
Exploring unfamiliar APIs: OpenAPI integration and link following make discovery easier.
Team workflows: Shared API configs mean consistent auth and base URLs across the team.
Documentation and examples: restish commands are more readable in docs and READMEs.
Migration Path
You don't have to go all-in immediately. Here's a practical approach:
# Install restish
brew install restish # macOS
# or
curl -fsSL https://rest.sh/install.sh | sh
# Configure your main API
restish api configure api.example.com
# Start using it for authenticated requests
restish get api.example.com/users
# Keep using curl for quick unauthenticated calls
curl https://api.example.com/healthGradually replace curl commands in your scripts and docs. You'll notice the difference within a week.
The Bigger Picture
We're in 2025. REST APIs have been mainstream for over a decade. The tooling should've evolved past manually typing HTTP headers and piping to jq.
restish isn't revolutionary. It's just common sense. It does for APIs what git did for version control—provides a domain-specific interface that actually understands what you're trying to do.
curl will always have a place for low-level HTTP work and non-REST protocols. But for modern REST APIs, restish is what you should be reaching for.
Getting Started
Install restish:
# macOS
brew install restish
# Linux
curl -fsSL https://rest.sh/install.sh | sh
# Windows
scoop install restishConfigure your first API:
# Auto-detect configuration
restish api configure api.example.com
# Or specify auth manually
restish api configure api.example.com \
--auth bearer \
--token YOUR_API_TOKENMake a request:
restish get api.example.com/endpointCheck the docs: https://rest.sh
Final Thoughts
curl is 27 years old. It's done its job admirably. But in 2025, when you're working with REST APIs, there's a better tool.
restish eliminates the boilerplate, handles authentication, understands JSON natively, and makes API exploration actually pleasant.
Try it for a week. You probably won't go back.
Resources:
Choose tools that match the problem. For REST APIs in 2025, that tool is restish.