How to Create API Design Patterns for ECC: A Complete Guide to RESTful Architecture

The ECC repository provides a comprehensive, language-agnostic API design skill located in skills/api-design/SKILL.md that defines eight core patterns for building production-ready REST APIs, including resource-first URL naming, standard response envelopes, pagination strategies, and authentication schemes.

The api-design skill in the ECC (Enterprise Coding Copilot) repository offers a reusable framework for creating consistent, secure, and evolvable APIs across any technology stack. According to the affaan-m/ECC source code, these patterns standardize everything from URL structure to error handling, ensuring that services built within the ECC ecosystem maintain uniformity and high quality.

Core Principles of the ECC API Design Pattern

The foundation of the ECC API design patterns rests on resource-oriented architecture and strict conventions for HTTP semantics. These rules ensure that APIs are predictable, cacheable, and easy to consume.

Resource-First URL Design

In skills/api-design/SKILL.md (lines 22-40), URLs are mandated to be nouns, plural, lowercase, and kebab-case. The resource-first approach means endpoints represent entities rather than actions.

  • Base URLs: Use /api/v1/users instead of /getUsers
  • Sub-resources: Nest related resources, e.g., /api/v1/users/{id}/orders
  • Actions: Reserve actions for true controllers, e.g., /api/v1/users/{id}/activate

This convention eliminates ambiguity and aligns with RESTful principles where HTTP methods define the action performed on the resource.

HTTP Method Semantics and Status Codes

Lines 58-89 of the skill specification map HTTP verbs to their idempotency and safety characteristics. Each method has prescribed status codes for success, client error, and server error scenarios.

Method mappings:

  • GET: Safe and idempotent; returns 200 OK or 404 Not Found
  • POST: Creates resources; returns 201 Created with a Location header or 422 Unprocessable Entity for validation errors
  • PUT/PATCH: Updates; returns 200 OK or 204 No Content
  • DELETE: Removes resources; returns 204 No Content or 404 Not Found

Standard Response Envelopes

Lines 114-172 define mandatory response envelopes that standardize client parsing. Success responses wrap data in a data field, while errors use a structured error object containing code, message, and optional details.

Success example:

{
  "data": {
    "id": "usr_123",
    "email": "user@example.com"
  }
}

Error example:

{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed",
    "details": ["email must be valid"]
  }
}

This envelope pattern ensures that clients can handle responses uniformly without inspecting HTTP status codes alone.

Advanced Patterns for Scalable APIs

Beyond the basics, ECC provides patterns for handling large datasets, complex queries, and security concerns.

Pagination Strategies

According to lines 198-246 of SKILL.md, ECC supports two pagination models:

Offset-based pagination (simple, page-number):

  • Use for datasets under 10,000 records
  • Query parameters: ?page=2&limit=25
  • Response includes total, page, size, and pages

Cursor-based pagination (scalable):

  • Use for large or rapidly changing datasets
  • Query parameters: ?cursor=eyJpZCI6MTIzfQ==&limit=25
  • Response includes next_cursor and has_more

Query String Conventions for Filtering and Sorting

Lines 248-286 define operators for advanced querying:

  • Equality: ?status=active
  • Range operators: ?created_at[gte]=2023-01-01&created_at[lte]=2023-12-31
  • Multi-value lists: ?status=active,pending
  • Nested fields: ?profile.name=John (dot notation)
  • Search: ?q=search term (full-text)

Authentication, Authorization, and Rate Limiting

Lines 294-324 specify token-based authentication using Authorization: Bearer <token> or X-API-Key headers. Resource-level and role-based middleware examples validate permissions before handling requests.

Lines 326-354 describe tiered rate limiting with header-based limits:

  • Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • Tiers: Anonymous (low), Authenticated (medium), Premium (high), Internal (unlimited)
  • Error: Returns 429 Too Many Requests when exceeded

API Versioning and Deprecation

Lines 356-384 mandate path-versioning (/api/v1/...) as the default strategy, with optional header-based versioning (API-Version: 2023-11). Deprecation workflows include Sunset headers and migration guides in the Deprecation header.

Implementation Examples

The ECC repository provides reference implementations demonstrating these patterns in TypeScript, Python, and Go.

TypeScript with Next.js

This example from skills/api-design/SKILL.md (lines 401-440) shows Zod validation, proper status codes, and the Location header:

import { z } from "zod";
import { NextRequest, NextResponse } from "next/server";

const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(100),
});

export async function POST(req: NextRequest) {
  const body = await req.json();
  const parsed = createUserSchema.safeParse(body);

  if (!parsed.success) {
    return NextResponse.json(
      { error: { code: "validation_error", message: "Request validation failed", details: parsed.error.issues } },
      { status: 422 }
    );
  }

  const user = await createUser(parsed.data);
  return NextResponse.json(
    { data: user },
    { status: 201, headers: { Location: `/api/v1/users/${user.id}` } }
  );
}

Python with Django REST Framework

Lines 442-476 demonstrate separate serializers for creation versus read operations, automatic headers, and error envelope handling:

from rest_framework import serializers, viewsets, status
from rest_framework.response import Response

class CreateUserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    name = serializers.CharField(max_length=100)

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "email", "name", "created_at"]

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def create(self, request):
        serializer = CreateUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = UserService.create(**serializer.validated_data)
        return Response(
            {"data": UserSerializer(user).data},
            status=status.HTTP_201_CREATED,
            headers={"Location": f"/api/v1/users/{user.id}"},
        )

Go with net/http

Lines 778-805 illustrate manual request decoding, validation, and response writing following ECC conventions:

func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
    var req CreateUserRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        writeError(w, http.StatusBadRequest, "invalid_json", "Invalid request body")
        return
    }

    if err := req.Validate(); err != nil {
        writeError(w, http.StatusUnprocessableEntity, "validation_error", err.Error())
        return
    }

    user, err := h.service.Create(r.Context(), req)
    if err != nil {
        // handle conflict, internal errors, etc.
        writeError(w, http.StatusInternalServerError, "internal_error", "Internal error")
        return
    }

    w.Header().Set("Location", fmt.Sprintf("/api/v1/users/%s", user.ID))
    writeJSON(w, http.StatusCreated, map[string]any{"data": user})
}

Summary

The ECC API design patterns provide a complete blueprint for RESTful architecture:

  • Resource-first URLs use plural, kebab-case nouns to represent entities, avoiding action verbs in paths
  • Standard response envelopes wrap success data in data keys and errors in structured error objects with codes and messages
  • HTTP semantics enforce idempotency rules and appropriate status codes (201 for creation, 422 for validation, 429 for rate limits)
  • Pagination supports both offset-based (for small datasets) and cursor-based (for large scale) strategies
  • Security layers include Bearer token authentication, tiered rate limiting, and role-based access control
  • Versioning uses path-based strategy (/api/v1/) with formal deprecation workflows

Frequently Asked Questions

What file contains the complete API design specification for ECC?

The complete specification resides in skills/api-design/SKILL.md in the affaan-m/ECC repository. This file contains line-by-line guidance on URL naming conventions, response envelopes, pagination, authentication, rate limiting, and versioning strategies applicable to any programming language.

How should I format error responses in ECC API design patterns?

Error responses must follow the standard envelope defined in lines 114-172 of the skill file. Wrap errors in an error object containing code (machine-readable string), message (human-readable description), and optional details (array of specific validation issues). Return appropriate HTTP status codes such as 422 for validation errors or 429 for rate limiting.

When should I use cursor-based pagination versus offset-based pagination?

Use offset-based pagination (page numbers) for datasets under 10,000 records where simplicity matters, as described in lines 198-220. Use cursor-based pagination for large datasets or rapidly changing data to prevent duplicate or skipped records during high-velocity writes, detailed in lines 221-246.

Does ECC API design require specific authentication mechanisms?

The patterns support token-based authentication via Authorization: Bearer <token> or X-API-Key headers, specified in lines 294-324. While the pattern is agnostic to the specific token format (JWT, opaque), it mandates that authentication middleware enforce resource-level and role-based checks before processing requests.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →