Best Practices

API Design Guidelines

Well-designed APIs are easy to use, document, and maintain. Follow these best practices to create OpenAPI specs that developers love.

Principles
  • Consistency - Use the same patterns throughout
  • Clarity - Make intentions obvious
  • Completeness - Document all behaviors
  • Discoverability - Help users explore your API

Naming Conventions

Paths: Use Kebab-Case Nouns

Good

/users
/user-profiles
/order-items
/api-keys

Avoid

/getUsers
/user_profiles
/OrderItems
/apiKeys
Schemas: Use PascalCase Nouns

Good

User
OrderItem
PaymentMethod
CreateUserRequest

Avoid

user
order_item
payment-method
createUserReq
Properties: Use camelCase

Good

firstName
createdAt
isActive
orderItems

Avoid

first_name
CreatedAt
is-active
order-items
Operation IDs: Use Verb + Noun

Good

listUsers
getUser
createOrder
updateUserProfile

Avoid

users
getUserById
order_create
update-user-profile

Resource Design

Use Standard HTTP Methods
MethodUsageExampleResponse
GETRead resource(s)GET /users200, 404
POSTCreate resourcePOST /users201, 400
PUTReplace resourcePUT /users/{id}200, 404
PATCHPartial updatePATCH /users/{id}200, 404
DELETERemove resourceDELETE /users/{id}204, 404
Use Hierarchical Paths for Relationships
# Good: Clear parent-child relationship
/users/{userId}/orders
/users/{userId}/orders/{orderId}
/orders/{orderId}/items
# Avoid: Flat structure hides relationships
/user-orders?userId=123
/order-items?orderId=456

Documentation Standards

Always Include These Fields
paths:
/users:
get:
# Short, action-focused
summary: List all users
# Detailed behavior explanation
description: |
Returns a paginated list of users.
Results are sorted by creation date (newest first).
# Unique, stable identifier
operationId: listUsers
# Group by feature
tags: [Users]
Document All Parameters
parameters:
- name: status
in: query
required: false
# Explain purpose and behavior
description: Filter by account status. Omit for all users.
schema:
type: string
enum: [active, inactive, pending]
# Show realistic value
example: active
Provide Examples
content:
application/json:
schema:
$ref: '#/components/schemas/User'
examples:
basic:
summary: Basic user
value:
id: "usr_123"
name: "John Doe"
email: "john@example.com"
admin:
summary: Admin user
value:
id: "usr_456"
name: "Admin User"
role: "admin"

Error Handling

Use Consistent Error Responses
components:
schemas:
Error:
type: object
required: [code, message]
properties:
code:
type: string
description: Machine-readable error code
example: "INVALID_EMAIL"
message:
type: string
description: Human-readable message
example: "The email format is invalid"
details:
type: array
description: Additional context for validation errors
items:
type: object
properties:
field:
type: string
reason:
type: string

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

Security Best Practices

Define Security at the Right Level

Use global security for the default, override per-operation only when needed.

Document All Auth Methods

Include descriptions for security schemes explaining how to obtain credentials.

Use Specific Scopes

Prefer fine-grained scopes (read:users, write:users) over broad ones (admin).

Mark Public Endpoints Explicitly

Use security: [] to clearly indicate no auth required.

Schema Design

Separate Create/Update/Response Schemas
components:
schemas:
# Full resource (responses)
User:
type: object
properties:
id: { type: string, readOnly: true }
email: { type: string }
name: { type: string }
createdAt: { type: string, readOnly: true }
# Create payload (no id, createdAt)
CreateUser:
type: object
required: [email, name]
properties:
email: { type: string }
name: { type: string }
# Update payload (all optional)
UpdateUser:
type: object
properties:
email: { type: string }
name: { type: string }

Use readOnly/writeOnly

id:
type: string
readOnly: true
password:
type: string
writeOnly: true

Mark Required Fields

type: object
required:
- email
- name
properties:
...

API Versioning

URL Path (Recommended)
/v1/users
/v2/users

Clear, visible, easy to route

Header
X-API-Version: 2
Accept-Version: v2

Clean URLs, harder to test

Query Parameter
/users?version=2

Easy override, clutters URLs

Quick Checklist

Before Publishing

All paths have descriptions
All parameters documented
Error responses defined
Security schemes configured

Quality Checks

Consistent naming conventions
Examples provided
Schemas reused via $ref
Validation passes
Related Topics
-> Schema Composition-> Authentication-> Real-World Examples-> Troubleshooting