DEV Community

Cover image for Why Is the Swagger Petstore Example a Bad REST API Design?
Wanda
Wanda

Posted on • Originally published at apidog.com

Why Is the Swagger Petstore Example a Bad REST API Design?

TL;DR

The Swagger Petstore is an outdated OpenAPI example that breaks REST fundamentals: inconsistent resource names, verbs in URLs, wrong HTTP status codes, passwords in GET requests, and bare arrays without metadata. Modern PetstoreAPI addresses these flaws with correct RESTful design, RFC 9457 error handling, and production-grade patterns.

Try Apidog today


Introduction

For over a decade, developers have looked to Swagger Petstore as the go-to OpenAPI example. But its design is flawed—leading countless APIs to inherit anti-patterns, security risks, and inconsistent conventions. Relying on it is like learning to drive with swapped brake and gas pedals: you’ll learn, but you’ll learn badly.

These issues propagate into production code, causing inconsistent naming, misused HTTP methods, and security vulnerabilities. Code reviews often overlook these problems because “that’s how Petstore does it.”

💡 Tip: Apidog helps you validate API design against REST principles, test endpoint behavior, and catch design flaws before they reach production. Import OpenAPI specs, run automated tests, and enforce REST conventions.

This guide breaks down what's wrong with Swagger Petstore, how it impacts your API, and how Modern PetstoreAPI solves these issues. You’ll see practical comparisons, actionable fixes, and how to test your API with Apidog.


The Swagger Petstore Legacy Problem

Swagger Petstore was created in 2011 to show how to write a Swagger (OpenAPI) spec—not as a REST API design reference.

Why It Became the De Facto Standard

Developers start with official examples. Swagger Petstore appears in docs, tutorials, and code generators. Many assume “official example = best practice” and copy its patterns into real APIs.

The Cost of Bad Examples

Poor examples lead to:

  1. Juniors learning anti-patterns (without realizing it)
  2. Code generators perpetuating issues (flawed SDKs)
  3. Docs tools showing bad patterns (Swagger UI defaults)
  4. Companies building bad APIs (assuming it’s “best practice”)

Swagger Petstore’s impact is massive—so its design flaws matter.


Critical REST Violations in Swagger Petstore

Let’s break down the main violations and how to fix them.

1. Inconsistent Resource Naming (Plural vs Singular)

Violation:

GET /pet/{petId}           # Singular
GET /store/inventory       # Plural
POST /pet                  # Singular
GET /user/{username}       # Singular
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:
REST collections should use plural nouns (e.g., /pets). Inconsistency makes it unclear whether you’re dealing with a collection or resource.

Modern PetstoreAPI Fix:

GET /pets/{petId}          # Always plural
GET /stores/inventory      # Consistent
POST /pets                 # Plural for collection
GET /users/{username}      # Plural everywhere
Enter fullscreen mode Exit fullscreen mode

See the REST API documentation for the full structure.


2. Action Verbs in URLs

Violation:

GET /pet/findByStatus?status=available
GET /pet/findByTags?tags=tag1,tag2
GET /user/login?username=john&password=secret
GET /user/logout
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:
RESTful URLs should represent resources (nouns), not actions (verbs). HTTP methods are the verbs. Verbs in paths indicate RPC thinking, not REST.

Modern PetstoreAPI Fix:

GET /pets?status=AVAILABLE            # Filter via query
GET /pets?tags=tag1,tag2              # Query parameter filtering
POST /auth/login                      # Separate auth resource
POST /auth/logout                     # RESTful auth endpoints
Enter fullscreen mode Exit fullscreen mode

See the authentication guide for proper patterns.


3. Wrong HTTP Status Codes

Violation:

POST /pet
# Response: 200 OK (should be 201 Created)

DELETE /pet/{petId}
# Response: 200 OK (should be 204 No Content)
# Body: { "message": "Pet deleted" }
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:

  • 200 OK is for successful resource retrieval.
  • 201 Created is for successful creation (with a Location header).
  • 204 No Content is for successful deletion (with no body).

Modern PetstoreAPI Fix:

POST /pets
# Response: 201 Created
# Location: /pets/{id}
{
  "id": "...",
  "name": "Fluffy",
  "status": "AVAILABLE"
}

DELETE /pets/{petId}
# Response: 204 No Content
# (no body)
Enter fullscreen mode Exit fullscreen mode

See the HTTP status codes guide for mapping.


4. Bare Arrays Without Metadata

Violation:

GET /pet/findByStatus?status=available
# Response: 200 OK
[
  {"id": 1, "name": "Fluffy"},
  {"id": 2, "name": "Buddy"}
]
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:

  • No pagination info
  • No extensibility for metadata or links
  • No HATEOAS
  • JSON Hijacking risk

Modern PetstoreAPI Fix:

{
  "data": [
    {"id": "...", "name": "Fluffy"},
    {"id": "...", "name": "Buddy"}
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "totalItems": 45,
    "totalPages": 3
  },
  "links": {
    "self": "/pets?status=AVAILABLE&page=1",
    "next": "/pets?status=AVAILABLE&page=2",
    "last": "/pets?status=AVAILABLE&page=3"
  }
}
Enter fullscreen mode Exit fullscreen mode

See the pagination guide for implementation.


5. Missing Error Standards

Violation:

{
  "code": 400,
  "message": "Invalid input"
}
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:

  • No error type identifier
  • No field-level validation
  • No machine-readable codes
  • Ignores RFC 9457 (“Problem Details”)

Modern PetstoreAPI Fix:

{
  "type": "https://petstoreapi.com/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Request validation failed",
  "instance": "/pets",
  "errors": [
    {
      "field": "name",
      "message": "Name is required",
      "code": "REQUIRED_FIELD"
    },
    {
      "field": "status",
      "message": "Status must be one of: AVAILABLE, PENDING, SOLD",
      "code": "INVALID_ENUM"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

See the error handling guide for complete format.


Security Disasters in the Old Design

Swagger Petstore has major security vulnerabilities.

GET Request with Passwords

Violation:

GET /user/login?username=john&password=secret123
Enter fullscreen mode Exit fullscreen mode

Why It’s a Disaster:

  • Passwords appear in browser history, server logs, referrer headers, proxies, bookmarks.
  • Never put credentials in URLs.

Modern PetstoreAPI Fix:

POST /auth/login
Content-Type: application/json
{
  "username": "john",
  "password": "secret123"
}

# Response: 200 OK
{
  "accessToken": "...",
  "refreshToken": "...",
  "expiresIn": 3600
}
Enter fullscreen mode Exit fullscreen mode

See the authentication guide for OAuth 2.0/JWT details.


API Keys in Query Parameters

Violation:

GET /pet/123?api_key=abc123secret
Enter fullscreen mode Exit fullscreen mode

Why It’s Wrong:
API keys in query params are logged, cached, and exposed like passwords.

Modern PetstoreAPI Fix:

GET /pets/{petId}
Authorization: Bearer <token>
Enter fullscreen mode Exit fullscreen mode

See the security guide for proper authentication.


How Modern PetstoreAPI Fixes These Issues

Modern PetstoreAPI is a reference for robust REST API design.

Production-Ready REST Design

  • Consistent plural naming: /pets, /orders, /users
  • Resource-oriented URLs: nouns only
  • Accurate HTTP status codes: 201, 204, proper errors
  • Wrapped collections: with pagination and metadata
  • RFC 9457 errors: structured, field-level validation

Modern Standards

  • OpenAPI 3.2
  • RFC 9457 (Problem Details)
  • IETF Rate Limiting (RateLimit-* headers)
  • ISO 8601 dates
  • UUIDv7 IDs

Multi-Protocol Support

Modern PetstoreAPI supports:

  • REST (OpenAPI 3.2)
  • GraphQL
  • gRPC
  • WebSocket
  • SSE
  • MQTT
  • Webhooks
  • MCP

See the protocols guide for details.

Real Business Logic

Includes:

  • Payment processing
  • Inventory
  • Orders
  • Webhooks
  • AI-powered recommendations
  • Image upload/processing

See the API documentation for all features.


Testing REST API Design with Apidog

Apidog lets you validate REST API design and catch issues early.

Import and Validate OpenAPI Specs

# Steps:
1. Open Apidog
2. Click "Import""OpenAPI"
3. Enter: https://petstoreapi.com/openapi.json
4. Apidog validates the spec and creates test cases
Enter fullscreen mode Exit fullscreen mode

Apidog will flag:

  • Inconsistent resource naming
  • Missing HTTP status codes
  • Invalid response structures
  • Security/authentication issues

Test REST Principles

Resource Names Are Plural

// Apidog test script
pm.test("Endpoint uses plural resource name", function() {
  const url = pm.request.url.toString();
  pm.expect(url).to.match(/\/pets\/|\/orders\/|\/users\//);
  pm.expect(url).to.not.match(/\/pet\/|\/order\/|\/user\//);
});
Enter fullscreen mode Exit fullscreen mode

Correct Status Codes

pm.test("POST returns 201 Created", function() {
  if (pm.request.method === "POST") {
    pm.response.to.have.status(201);
    pm.response.to.have.header("Location");
  }
});

pm.test("DELETE returns 204 No Content", function() {
  if (pm.request.method === "DELETE") {
    pm.response.to.have.status(204);
    pm.expect(pm.response.text()).to.be.empty;
  }
});
Enter fullscreen mode Exit fullscreen mode

Collections Have Metadata

pm.test("Collection response includes pagination", function() {
  const response = pm.response.json();
  pm.expect(response).to.have.property("data");
  pm.expect(response).to.have.property("pagination");
  pm.expect(response.pagination).to.have.property("page");
  pm.expect(response.pagination).to.have.property("totalItems");
});
Enter fullscreen mode Exit fullscreen mode

Compare Old vs New Petstore

  1. Import Swagger Petstore: https://petstore.swagger.io/v2/swagger.json
  2. Import Modern PetstoreAPI: https://petstoreapi.com/openapi.json
  3. Run automated tests on both
  4. Compare results side-by-side

Apidog will highlight Swagger Petstore’s design violations and Modern PetstoreAPI’s fixes.


Migration Guide: Old Petstore to Modern Design

Migrating from Swagger Petstore? Follow these actionable steps.

Step 1: Fix Resource Names

Before:

GET /pet/{petId}
POST /pet
DELETE /pet/{petId}
Enter fullscreen mode Exit fullscreen mode

After:

GET /pets/{petId}
POST /pets
DELETE /pets/{petId}
Enter fullscreen mode Exit fullscreen mode

Strategy:

  • Support both endpoints during transition
  • Add deprecation warnings to old endpoints
  • Update docs to show new endpoints
  • Remove old endpoints after 6 months

Step 2: Remove Action Verbs

Before:

GET /pet/findByStatus?status=available
GET /pet/findByTags?tags=tag1,tag2
Enter fullscreen mode Exit fullscreen mode

After:

GET /pets?status=AVAILABLE
GET /pets?tags=tag1,tag2
Enter fullscreen mode Exit fullscreen mode

Strategy:

  • Redirect old endpoints to new (301 Moved Permanently)
  • Update client SDKs
  • Add query parameter validation

Step 3: Fix HTTP Status Codes

Before:

POST /pet → 200 OK
DELETE /pet/{petId} → 200 OK with body
Enter fullscreen mode Exit fullscreen mode

After:

POST /pets → 201 Created with Location header
DELETE /pets/{petId} → 204 No Content (no body)
Enter fullscreen mode Exit fullscreen mode

Strategy:

  • Breaking change: version your API (e.g., v2)
  • Document changes clearly
  • Provide migration timeline

Step 4: Wrap Collections

Before:

[
  {"id": 1, "name": "Fluffy"},
  {"id": 2, "name": "Buddy"}
]
Enter fullscreen mode Exit fullscreen mode

After:

{
  "data": [...],
  "pagination": {...},
  "links": {...}
}
Enter fullscreen mode Exit fullscreen mode

Strategy:

  • Breaking change: create v2 endpoints with wrapped responses
  • Deprecate v1 endpoints
  • Update client code

Step 5: Implement RFC 9457 Errors

Before:

{
  "code": 400,
  "message": "Invalid input"
}
Enter fullscreen mode Exit fullscreen mode

After:

{
  "type": "https://petstoreapi.com/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Request validation failed",
  "errors": [...]
}
Enter fullscreen mode Exit fullscreen mode

Strategy:

  • Add Content-Type: application/problem+json header
  • Support both formats during transition
  • Update client error handling
  • Remove old format after migration

Real-World Impact of Bad API Design

Developer Confusion

Violating REST principles causes:

  • Guesswork on HTTP methods
  • Inconsistent naming headaches
  • Unexpected status codes
  • Error handling confusion

Cost: Hours lost per integration.

Client Bugs

Leads to:

  • Parsing errors from inconsistent responses
  • Auth failures from wrong methods
  • Pagination bugs from missing metadata
  • Poor error handling

Cost: Production incidents and customer issues.

Security Vulnerabilities

Design flaws lead to:

  • Passwords and keys in logs/history
  • Missing auth on sensitive endpoints
  • Error messages leaking system info

Cost: Data breaches and compliance risks.

Technical Debt

Bad patterns compound:

  • New devs copy anti-patterns
  • Code generators spread flaws
  • Docs show incorrect examples

Cost: Long-term maintenance pain.


Conclusion

Swagger Petstore was a simple OpenAPI demo, but its REST violations and anti-patterns are no longer acceptable. Modern PetstoreAPI is the reference you should follow for robust RESTful APIs: proper naming, modern standards, multi-protocol support, production-ready features.

Test your APIs with Apidog to catch design errors early. Import your OpenAPI specs, run automated tests, and ensure your APIs meet REST principles before launch.

Next Steps:

  1. Explore Modern PetstoreAPI documentation
  2. Compare your API to Modern PetstoreAPI patterns
  3. Import your OpenAPI spec into Apidog for validation
  4. Fix REST violations using the migration guide above
  5. Adopt RFC 9457 for error handling

The era of bad API examples is over. Build APIs the right way with Modern PetstoreAPI.


FAQ

Why did Swagger create a bad example?

Swagger Petstore was a 2011 demo for the Swagger spec, not a REST API reference. Unfortunately, it became the default example, and its flaws were copied everywhere.

Should I stop using Swagger Petstore?

Yes, for REST API design. Use Modern PetstoreAPI instead—it demonstrates correct REST principles, standards, and production patterns.

Is Modern PetstoreAPI production-ready?

Yes. Modern PetstoreAPI includes realistic business logic, proper error handling, authentication, rate limiting, and security features. Use it as a template or direct reference.

How do I test if my API follows REST principles?

Import your OpenAPI spec into Apidog and run automated tests. It validates naming, status codes, response structures, and security.

What’s the biggest mistake in Swagger Petstore?

Using GET /user/login with passwords in the URL—a critical security flaw. Always use POST with JSON bodies for authentication.

Can I migrate from Swagger Petstore patterns gradually?

Yes. Support both old and new endpoints during transition. Add deprecation warnings, update docs, monitor usage, and remove old endpoints after client migration (6–12 months).

Does Modern PetstoreAPI support GraphQL and gRPC?

Yes. Modern PetstoreAPI supports REST, GraphQL, gRPC, WebSocket, SSE, MQTT, Webhooks, and MCP. See the protocols guide for details.

How do I convince my team to fix our API design?

Show the real costs: developer confusion, client bugs, security risks, and technical debt. Use Apidog to demonstrate issues in your current API and compare with Modern PetstoreAPI.


Top comments (0)