Skip to main content
~/blog

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:

bash
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:

bash
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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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)

bash
# 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)

bash
# 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

bash
# 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
bash
# 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

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

# curl needs shell history hacks
history | grep curl

4. API Profiles

bash
# 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:

bash
# 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:

bash
# macOS
brew install restish

# Linux
curl -fsSL https://rest.sh/install.sh | sh

# Windows
scoop install restish

Configure your first API:

bash
# 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:

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