---
name: openapi-spec-patterns
description: "OpenAPI 3.x spec analysis patterns, schema normalization, authentication method mapping, pagination/error pattern extraction, and GraphQL/gRPC spec interpretation guide. Use this skill for requests involving 'OpenAPI', 'Swagger', 'spec analysis', 'schema normalization', 'API authentication', 'pagination patterns', 'GraphQL schema', 'gRPC proto', etc. Enhances spec-parser's spec analysis capabilities. Note: SDK code generation and test authoring are outside the scope of this skill."
---
# OpenAPI Spec Patterns — API Spec Analysis Patterns Guide
Methodology for effectively analyzing OpenAPI/GraphQL/gRPC specs and extracting the metadata needed for SDK generation.
## OpenAPI 3.x Analysis Procedure
### 1. Endpoint Grouping
```yaml
# Tag-based grouping -> SDK class mapping
paths:
/users:
get:
tags: [Users] # -> UsersClient.list()
post:
tags: [Users] # -> UsersClient.create()
/users/{id}:
get:
tags: [Users] # -> UsersClient.get(id)
put:
tags: [Users] # -> UsersClient.update(id, data)
delete:
tags: [Users] # -> UsersClient.delete(id)
/users/{id}/orders:
get:
tags: [Users, Orders] # -> UsersClient.listOrders(id)
```
### Mapping Rules
| HTTP Method | Pattern | SDK Method Name |
|------------|---------|----------------|
| GET /resources | List | `list()` |
| GET /resources/{id} | Detail | `get(id)` |
| POST /resources | Create | `create(data)` |
| PUT /resources/{id} | Full update | `update(id, data)` |
| PATCH /resources/{id} | Partial update | `patch(id, data)` |
| DELETE /resources/{id} | Delete | `delete(id)` |
| POST /resources/{id}/action | Action | `actionName(id, data)` |
### 2. Authentication Method Mapping
```yaml
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.example.com/authorize
tokenUrl: https://auth.example.com/token
scopes:
read: Read access
write: Write access
```
| Auth Type | SDK Implementation | Code Pattern |
|----------|-------------------|-------------|
| Bearer | Header interceptor | `Authorization: Bearer {token}` |
| API Key | Header/query interceptor | `X-API-Key: {key}` |
| OAuth2 | Token manager + refresh | Auto refresh_token handling |
| Basic | Header | `Authorization: Basic {base64}` |
### 3. Pagination Pattern Detection
```yaml
# Pattern 1: Offset-based
parameters:
- name: offset
in: query
schema: { type: integer }
- name: limit
in: query
schema: { type: integer, default: 20 }
# Pattern 2: Cursor-based
parameters:
- name: cursor
in: query
schema: { type: string }
- name: limit
in: query
schema: { type: integer }
# Pattern 3: Page-based
parameters:
- name: page
in: query
schema: { type: integer }
- name: per_page
in: query
schema: { type: integer }
```
| Detection Pattern | SDK Implementation |
|------------------|-------------------|
| offset/limit | `listAll()` auto page traversal |
| cursor/after | `iterate()` iterator |
| page/per_page | `listPage(page)` |
| Link header | HTTP Link header parsing |
### 4. Error Response Patterns
```yaml
# Standard error structure extraction
responses:
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
type: object
properties:
code: { type: string }
message: { type: string }
details: { type: array, items: { $ref: '#/components/schemas/ErrorDetail' } }
```
### SDK Error Class Mapping
| HTTP Status | SDK Exception | Retry |
|------------|--------------|-------|
| 400 | BadRequestError | No |
| 401 | AuthenticationError | No (once after token refresh) |
| 403 | PermissionError | No |
| 404 | NotFoundError | No |
| 409 | ConflictError | No |
| 422 | ValidationError | No |
| 429 | RateLimitError | Yes (Retry-After) |
| 500 | InternalError | Yes (exponential backoff) |
| 502/503/504 | ServiceUnavailableError | Yes |
## Schema Normalization
### Circular Reference Handling
```yaml
# Circular: User -> Order -> User
User:
properties:
orders:
type: array
items: { $ref: '#/components/schemas/Order' }
Order:
properties:
user: { $ref: '#/components/schemas/User' } # Circular!
# Resolution: Lazy Reference
# TypeScript: type User = { orders: () => Order[] }
# Python: User = ForwardRef('User')
```
### allOf/oneOf/anyOf Interpretation
```yaml
# allOf -> Intersection (inheritance/extension)
UpdateUser:
allOf:
- $ref: '#/components/schemas/BaseUser'
- type: object
properties:
password: { type: string }
# -> class UpdateUser extends BaseUser { password?: string }
# oneOf -> Union (exclusive choice)
Pet:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
discriminator:
propertyName: petType
# -> type Pet = Cat | Dog (discriminated union)
# anyOf -> Flexible union
Filter:
anyOf:
- type: string
- type: integer
- type: array
items: { type: string }
# -> type Filter = string | number | string[]
```
## GraphQL Schema Analysis
```graphql
# Query -> SDK read methods
type Query {
user(id: ID!): User # -> client.users.get(id)
users(first: Int, after: String): UserConnection # -> client.users.list()
}
# Mutation -> SDK write methods
type Mutation {
createUser(input: CreateUserInput!): User # -> client.users.create(input)
updateUser(id: ID!, input: UpdateUserInput!): User
}
# Connection pattern -> Auto-pagination
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
}
```
## gRPC Proto Analysis
```protobuf
service UserService {
rpc GetUser (GetUserRequest) returns (User); // -> client.getUser(id)
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
rpc CreateUser (CreateUserRequest) returns (User);
rpc StreamUsers (StreamRequest) returns (stream User); // -> Streaming API
}
```
| gRPC Pattern | SDK Implementation |
|-------------|-------------------|
| Unary | Standard async method |
| Server Stream | AsyncIterator |
| Client Stream | Stream send method |
| Bidirectional | Bidirectional stream |