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.

| 4 min read
api cli devtools rest

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.com

That’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/users

With 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/users

restish 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 csv

No 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 parameters

restish 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"}' | jq

The 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-developer

Less 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.json
# 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=2

3. Request History

# restish keeps history
restish history
restish rerun 5  # Re-run command #5

# curl needs shell history hacks
history | grep curl

4. 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 swapping

When 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/health

Gradually 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 restish

Configure 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_TOKEN

Make a request:

restish get api.example.com/endpoint

Check 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.