cosmix

api-design

6
0
# Install this skill:
npx skills add cosmix/loom --skill "api-design"

Install specific skill from multi-skill repository

# Description

Designs RESTful APIs, GraphQL schemas, and RPC interfaces following best practices for consistency, usability, and scalability. Trigger keywords: api design, REST, RESTful, REST API, GraphQL, GraphQL schema, gRPC, OpenAPI, Swagger, endpoint, route, resource, CRUD, HTTP method, GET, POST, PUT, PATCH, DELETE, status code, pagination, filtering, sorting, versioning, HATEOAS, API versioning, schema design, RPC, service design.

# SKILL.md


name: api-design
description: Designs RESTful APIs, GraphQL schemas, and RPC interfaces following best practices for consistency, usability, and scalability. Trigger keywords: api design, REST, RESTful, REST API, GraphQL, GraphQL schema, gRPC, OpenAPI, Swagger, endpoint, route, resource, CRUD, HTTP method, GET, POST, PUT, PATCH, DELETE, status code, pagination, filtering, sorting, versioning, HATEOAS, API versioning, schema design, RPC, service design.
allowed-tools: Read, Grep, Glob, Edit, Write


API Design

Overview

This skill guides the design of well-structured APIs that are intuitive, consistent, and scalable. It covers REST, GraphQL, and gRPC patterns with focus on developer experience and long-term maintainability.

Instructions

1. Understand Requirements

  • Identify API consumers and use cases
  • Define resource models and relationships
  • Determine authentication/authorization needs
  • Plan for versioning strategy

2. Design Resource Structure

  • Define clear resource hierarchies
  • Establish naming conventions
  • Plan URL patterns
  • Design request/response schemas

3. Define Operations

  • Map CRUD operations to HTTP methods
  • Design query parameters for filtering/sorting
  • Plan pagination approach
  • Define error response formats

4. Document the API

  • Create OpenAPI/Swagger specification
  • Include examples for all endpoints
  • Document authentication flows
  • Provide SDK usage examples

Best Practices

RESTful API Design

  1. Use Nouns for Resources: /users, not /getUsers
  2. Consistent Naming: Use snake_case or camelCase consistently across all endpoints
  3. Proper HTTP Methods:
  4. GET (read/fetch), POST (create), PUT (full update), PATCH (partial update), DELETE (remove)
  5. Meaningful Status Codes:
  6. 200 (OK), 201 (Created), 204 (No Content)
  7. 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), 404 (Not Found)
  8. 409 (Conflict), 422 (Unprocessable Entity)
  9. 500 (Internal Server Error), 503 (Service Unavailable)
  10. Idempotency: PUT and DELETE should be idempotent; consider idempotency keys for POST
  11. HATEOAS: Include links to related resources in responses
  12. Filtering & Sorting: Use query parameters (?status=active&sort=-created_at)
  13. Pagination: Cursor-based for large datasets, offset for simpler cases

GraphQL Schema Design

  1. Use Descriptive Types: Clear, self-documenting type and field names
  2. Connection Pattern: Use relay-style connections for paginated lists
  3. Input Objects: Separate input types for mutations (CreateUserInput, UpdateUserInput)
  4. Error Handling: Return errors as part of payload, not just top-level exceptions
  5. Nullability: Be explicit about nullable vs non-nullable fields
  6. Mutations Return Payloads: Include both data and errors in mutation responses
  7. Avoid Over-fetching: Design fragments and fields for common query patterns

gRPC Service Design

  1. Service Naming: Use verbs for RPC methods (CreateUser, GetUser, ListUsers)
  2. Message Reuse: Define shared message types for common patterns
  3. Pagination: Use page_token pattern for cursor-based pagination
  4. Errors: Use google.rpc.Status for rich error details
  5. Versioning: Use package versioning (myapi.v1, myapi.v2)
  6. Streaming: Leverage server/client/bidirectional streaming where appropriate

API Versioning Strategies

  1. URL Path Versioning: /v1/users, /v2/users (explicit, simple, cacheable)
  2. Header Versioning: API-Version: 2 or Accept: application/vnd.api.v2+json (cleaner URLs)
  3. Query Parameter: ?version=2 (fallback option, less recommended)
  4. Semantic Versioning: Major versions for breaking changes, minor for features, patch for fixes
  5. Deprecation Policy: Announce sunset dates, support N-1 versions minimum

Examples

Example 1: RESTful Resource Design

# OpenAPI 3.0 Specification
openapi: 3.0.0
info:
  title: E-Commerce API
  version: 1.0.0

paths:
  /products:
    get:
      summary: List all products
      parameters:
        - name: category
          in: query
          schema:
            type: string
        - name: min_price
          in: query
          schema:
            type: number
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: per_page
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        "200":
          description: Paginated list of products
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Product"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

    post:
      summary: Create a new product
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductInput"
      responses:
        "201":
          description: Product created
        "400":
          description: Validation error

  /products/{id}:
    get:
      summary: Get a specific product
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Product details
        "404":
          description: Product not found

Example 2: GraphQL Schema Design

type Query {
  """
  Fetch a user by ID
  """
  user(id: ID!): User

  """
  List users with optional filtering
  """
  users(filter: UserFilter, first: Int = 20, after: String): UserConnection!
}

type Mutation {
  """
  Create a new user account
  """
  createUser(input: CreateUserInput!): CreateUserPayload!

  """
  Update an existing user
  """
  updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}

type User {
  id: ID!
  email: String!
  name: String!
  createdAt: DateTime!
  orders(first: Int, after: String): OrderConnection!
}

input CreateUserInput {
  email: String!
  name: String!
  password: String!
}

type CreateUserPayload {
  user: User
  errors: [UserError!]!
}

type UserError {
  field: String
  message: String!
  code: UserErrorCode!
}

Example 3: gRPC Service Definition

syntax = "proto3";

package ecommerce.v1;

import "google/protobuf/timestamp.proto";

service ProductService {
  // Fetch a single product by ID
  rpc GetProduct(GetProductRequest) returns (GetProductResponse);

  // List products with filtering and pagination
  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse);

  // Create a new product
  rpc CreateProduct(CreateProductRequest) returns (CreateProductResponse);

  // Update an existing product
  rpc UpdateProduct(UpdateProductRequest) returns (UpdateProductResponse);

  // Delete a product
  rpc DeleteProduct(DeleteProductRequest) returns (DeleteProductResponse);
}

message Product {
  string id = 1;
  string name = 2;
  string description = 3;
  int64 price_cents = 4;
  string category = 5;
  google.protobuf.Timestamp created_at = 6;
  google.protobuf.Timestamp updated_at = 7;
}

message ListProductsRequest {
  // Optional category filter
  string category = 1;

  // Minimum price filter (in cents)
  optional int64 min_price_cents = 2;

  // Maximum number of items to return
  int32 page_size = 3;

  // Page token from previous response
  string page_token = 4;
}

message ListProductsResponse {
  repeated Product products = 1;
  string next_page_token = 2;
  int32 total_count = 3;
}

message CreateProductRequest {
  string name = 1;
  string description = 2;
  int64 price_cents = 3;
  string category = 4;
}

message CreateProductResponse {
  Product product = 1;
}

Example 4: Error Response Design (REST)

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "email",
        "code": "INVALID_FORMAT",
        "message": "Email must be a valid email address"
      },
      {
        "field": "age",
        "code": "OUT_OF_RANGE",
        "message": "Age must be between 18 and 120"
      }
    ],
    "request_id": "req_abc123xyz",
    "documentation_url": "https://api.example.com/docs/errors#VALIDATION_ERROR"
  }
}

Example 5: API Versioning with Header

# Request with API version header
GET /users/123 HTTP/1.1
Host: api.example.com
Accept: application/vnd.api.v2+json
Authorization: Bearer eyJ...

# Response includes deprecation warning
HTTP/1.1 200 OK
Content-Type: application/vnd.api.v2+json
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Deprecation: true
Link: <https://api.example.com/v3/users/123>; rel="successor-version"

{
  "id": "123",
  "email": "[email protected]",
  "name": "John Doe"
}

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.