API Strategy & Design

Design RESTful and GraphQL APIs, implement versioning, create OpenAPI specs, and build developer-friendly APIs that scale.

⏱️ 50 minutes 📊 Intermediate 📝 5 steps 🏷️ Digital Ecosystem

Prerequisites

  • Understanding of HTTP protocols
  • Basic knowledge of web development
  • Familiarity with JSON
  • Understanding of REST concepts

Learning Objectives

  • Design RESTful APIs following best practices
  • Create comprehensive OpenAPI specifications
  • Implement API versioning strategies
  • Design GraphQL schemas for flexible queries
  • Build developer-friendly documentation

Step-by-Step Guide

1RESTful API Design Principles

Learn the core principles of RESTful API design.

# RESTful Design Principles

# 1. Use Nouns, Not Verbs
# ❌ Bad: GET /getUsers, POST /createUser
# ✅ Good: GET /users, POST /users

# 2. Use Plural Nouns
# ❌ Bad: GET /user/123
# ✅ Good: GET /users/123

# 3. Use HTTP Methods Correctly
# GET    - Retrieve resources (idempotent)
# POST   - Create new resources
# PUT    - Replace entire resource (idempotent)
# PATCH  - Partial update (not idempotent)
# DELETE - Remove resources (idempotent)

# 4. Use HTTP Status Codes Properly
# 200 OK          - Successful GET, PUT, PATCH
# 201 Created     - Successful POST
# 204 No Content  - Successful DELETE
# 400 Bad Request - Invalid input
# 401 Unauthorized - Authentication required
# 403 Forbidden   - Authentication OK, no permission
# 404 Not Found   - Resource does not exist
# 422 Unprocessable Entity - Validation error
# 429 Too Many Requests - Rate limit exceeded

# 5. Implement Filtering, Sorting, Pagination
GET /users?role=admin&status=active
GET /users?sort=-created_at&order=desc
GET /users?page=2&limit=20

# 6. Use Proper Error Responses
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input data",
    "details": [
      {"field": "email", "message": "Invalid email format"},
      {"field": "password", "message": "Must be at least 8 characters"}
    ]
  }
}

2OpenAPI Specification

Create comprehensive API documentation using OpenAPI 3.1.

openapi: "3.1.0"
info:
  title: Ecosystem Platform API
  description: API for managing digital ecosystems
  version: "2.1.0"
  contact:
    email: api-support@platform.com

servers:
  - url: https://api.platform.com/v2
    description: Production
  - url: https://staging-api.platform.com/v2
    description: Staging

paths:
  /ecosystems:
    get:
      summary: List all ecosystems
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Ecosystem'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
    
    post:
      summary: Create a new ecosystem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name:
                  type: string
                description:
                  type: string
      responses:
        '201':
          description: Ecosystem created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ecosystem'

  /ecosystems/{id}:
    get:
      summary: Get ecosystem by ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful response
        '404':
          description: Not found

components:
  schemas:
    Ecosystem:
      type: object
      required: [id, name, status, created_at]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        status:
          type: string
          enum: [active, inactive, archived]
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Pagination:
      type: object
      properties:
        page:
          type: integer
        limit:
          type: integer
        total:
          type: integer
        has_next:
          type: boolean

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - BearerAuth: []

3API Versioning Strategies

Implement proper API versioning for backward compatibility.

# API Versioning Strategies

# Strategy 1: URL Versioning (Most Common)
GET /v1/users
GET /v2/users

# Strategy 2: Header Versioning
GET /users
Headers:
  API-Version: 2024-01-01

# Versioning Best Practices

# 1. Use Semantic Versioning (MAJOR.MINOR.PATCH)
# - MAJOR: Breaking changes
# - MINOR: Backward-compatible features
# - PATCH: Backward-compatible fixes

# 2. Deprecation Policy
Warning: 299 - "API v1 deprecated. Migrate to v2 by 2025-12-31"
Deprecation: true
Sunset: Sat, 31 Dec 2025 23:59:59 GMT

# 3. Breaking Changes (require new major version)
# - Removing endpoints
# - Removing/renaming fields
# - Changing field types

# 4. Non-Breaking Changes (same version)
# - Adding new endpoints
# - Adding optional fields
# - Performance improvements

# Implementation Example
const versionMiddleware = (version) => {
  return (req, res, next) => {
    const urlVersion = req.path.match(/^\/v(\d+)/)?.[1];
    const headerVersion = req.headers['api-version'];
    const requestedVersion = urlVersion || headerVersion;
    
    if (requestedVersion !== version) {
      return res.status(400).json({
        error: { code: 'INVALID_VERSION', message: `Requires API version ${version}` }
      });
    }
    req.apiVersion = requestedVersion;
    next();
  };
};

// Usage
app.use('/v1/users', versionMiddleware('1'), v1UserRoutes);
app.use('/v2/users', versionMiddleware('2'), v2UserRoutes);

4GraphQL Schema Design

Design flexible GraphQL schemas for complex queries.

# GraphQL Schema Definition
type Query {
  ecosystem(id: ID!): Ecosystem
  ecosystems(filters: EcosystemFilterInput, pagination: PaginationInput!): EcosystemConnection!
  searchEcosystems(query: String!): [Ecosystem!]!
}

type Mutation {
  createEcosystem(input: CreateEcosystemInput!): EcosystemMutationResponse!
  updateEcosystem(id: ID!, input: UpdateEcosystemInput!): EcosystemMutationResponse!
  deleteEcosystem(id: ID!): DeleteResponse!
}

type Subscription {
  ecosystemCreated: Ecosystem!
  ecosystemUpdated(id: ID!): Ecosystem!
}

type Ecosystem {
  id: ID!
  name: String!
  description: String
  status: EcosystemStatus!
  participantsCount: Int!
  createdAt: DateTime!
  updatedAt: DateTime!
  
  participants(pagination: PaginationInput!): ParticipantConnection!
  integrations: [Integration!]!
}

type Participant {
  id: ID!
  name: String!
  email: String!
  role: ParticipantRole!
  status: ParticipantStatus!
  ecosystems: [Ecosystem!]!
}

input CreateEcosystemInput {
  name: String!
  description: String
  settings: JSON
}

input PaginationInput {
  page: Int = 1
  limit: Int = 20
  sortBy: SortField = CREATED_AT
  sortOrder: Order = DESC
}

enum EcosystemStatus {
  ACTIVE
  INACTIVE
  ARCHIVED
}

enum ParticipantRole {
  ADMIN
  MEMBER
  VIEWER
}

scalar DateTime
scalar JSON

# Example Query
query GetEcosystem {
  ecosystem(id: "550e8400-e29b-41d4-a716-446655440000") {
    id
    name
    status
    participants(pagination: { limit: 10 }) {
      edges {
        node {
          id
          name
          email
        }
      }
    }
  }
}

5API Documentation & Developer Experience

Create excellent API documentation for developers.

# Generate Interactive API Documentation

# Using Swagger UI
npm install swagger-ui-express

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');

const app = express();
const swaggerDoc = YAML.load('openapi.yaml');

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc, {
  customSiteTitle: 'Platform API Documentation',
  docExpansion: 'list',
  filter: true
}));

# API Documentation Best Practices

# 1. Getting Started Guide
# Include:
# - Authentication examples
# - Quick start code samples
# - SDK links

# 2. Code Examples in Multiple Languages
# JavaScript/TypeScript
const api = new PlatformAPI('YOUR_API_KEY');
const ecosystem = await api.ecosystems.create({ name: 'My Ecosystem' });

# Python
from platform_sdk import PlatformAPI
api = PlatformAPI(api_key='YOUR_API_KEY')
ecosystem = api.ecosystems.create(name='My Ecosystem')

# cURL
curl -X POST https://api.platform.com/v2/ecosystems \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Ecosystem"}'

# 3. Error Handling Guide
# Document all error codes and formats
# Include retry logic for rate limits

# 4. SDKs and Libraries
# Provide official SDKs for major languages
# Maintain community-contributed packages

Best Practices

API Design Principles:
  • Design First: Write OpenAPI spec before implementation
  • Be Consistent: Use same patterns across all endpoints
  • Document Everything: Auto-generate docs from specs
  • Version Carefully: Plan for backward compatibility
  • Rate Limit: Protect your API from abuse
  • Monitor Usage: Track errors, latency, adoption

Assessment

1. Which HTTP method should be used to create a new resource?

2. What does REST stand for?

3. Which HTTP status code indicates a successful resource creation?

4. What is the recommended approach for API versioning?

Answer Key: 1-B, 2-A, 3-B, 4-B

Resources