agentsclimarketplace

Api design

Skill rynhardt-potgieter/sprint_workflow/plugins/sprint-workflow/skills/api-design

A portable Claude Code plugin system for orchestrating software development through parallel specialist agents, enforced engineering standards, and automated quality gates. One command to plan. Parallel agents to build. Automated gates to ship.

Install
npx -y skills add rynhardt-potgieter/sprint_workflow --skill api-design

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

RESTful API design standards — endpoint naming, HTTP methods, response wrappers, error handling (RFC 7807), pagination, versioning, rate limiting, and OpenAPI conventions. Use this skill when designing new API endpoints, reviewing API contracts, adding error handling, implementing pagination, or ensuring API consistency across the project.

SKILL.md

5.8 KB, as published. Nobody here has run it

RESTful API Design Standards

This skill defines authoritative patterns for all API design across projects.

URL Structure

Resource Naming

GET    /api/goals              # List goals (paginated)
GET    /api/goals/{id}         # Get single goal
POST   /api/goals              # Create goal
PUT    /api/goals/{id}         # Full update
PATCH  /api/goals/{id}         # Partial update
DELETE /api/goals/{id}         # Delete goal

Rules

  • Nouns, not verbs: /api/goals, not /api/getGoals
  • Plural: /api/goals, not /api/goal
  • Lowercase kebab-case for multi-word: /api/fund-bundles, not /api/fundBundles
  • Nested resources for containment: /api/goals/{goalId}/positions
  • Max 2 levels of nesting: Beyond that, promote to top-level with query filters
  • Actions as sub-resources: POST /api/goals/{id}/archive (not PUT /api/goals/{id} with { archived: true })

HTTP Methods & Status Codes

MethodPurposeSuccess CodeBody
GETRead200Resource or list
POSTCreate201Created resource + Location header
PUTFull replace200Updated resource
PATCHPartial update200Updated resource
DELETERemove204No body

Error Codes

CodeMeaningWhen
400Bad RequestValidation failures, malformed input
401UnauthorizedMissing/invalid token
403ForbiddenValid token, insufficient permissions
404Not FoundResource doesn't exist
409ConflictDuplicate resource, concurrency conflict
422Unprocessable EntityBusiness rule violation
429Too Many RequestsRate limit exceeded
500Server ErrorUnhandled exception (log + generic message)

Response Wrappers

Success Response

{
  "data": { "id": "...", "name": "Emergency Fund", ... },
  "success": true,
  "message": null
}

Error Response (RFC 7807-inspired)

{
  "data": null,
  "success": false,
  "message": "Goal target amount must be positive",
  "errors": ["TargetAmount must be greater than 0"]
}

Paginated Response

{
  "items": [...],
  "totalItems": 42,
  "pageNumber": 1,
  "pageSize": 20,
  "hasNextPage": true
}

Implementation

public static class ApiResponse
{
    public static ApiResponse<T> Ok<T>(T data, string? message = null)
        => new(data, true, message);
    public static ApiResponse<T> Fail<T>(string message, params string[] errors)
        => new(default, false, message, errors);
}

Pagination

Query Parameters

GET /api/goals?page=1&pageSize=20&sortBy=createdAt&sortDir=desc
  • Default pageSize: 20, max: 100
  • Default sortDir: desc (newest first)
  • Always return totalItems and hasNextPage

Cursor-Based (For Large Datasets)

GET /api/activity?cursor=eyJpZCI6MTIzfQ&limit=20

Use cursor pagination when offset-based becomes expensive (>10K rows).

Filtering & Search

GET /api/goals?status=active&type=emergency&search=house
  • Simple filters: query parameters matching field names
  • Search: search parameter for free-text across multiple fields
  • Date ranges: createdAfter=2025-01-01&createdBefore=2025-12-31
  • Never filter on sensitive fields (password, tokens)

Request Validation

Controller Level

[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateGoalRequest request, CancellationToken ct)
{
    if (string.IsNullOrWhiteSpace(request.Name))
        return BadRequest(ApiResponse.Fail<GoalDto>("Name is required"));

    // Or use FluentValidation / DataAnnotations
}

DTO Naming

  • Requests: CreateGoalRequest, UpdateGoalRequest
  • Responses: GoalDto, GoalSummaryDto
  • Service results: TradeResult, XpAwardResult

Versioning Strategy

For breaking changes only:

/api/v2/goals    # URL path versioning (preferred for simplicity)

Non-breaking changes (adding fields, new endpoints) don't need versioning.

OpenAPI / Swagger

[HttpGet("{id:guid}")]
[ProducesResponseType<ApiResponse<GoalDto>>(200)]
[ProducesResponseType(404)]
[ProducesResponseType(401)]
public async Task<IActionResult> GetById(Guid id, CancellationToken ct) { ... }
  • Always specify ProducesResponseType for documentation
  • Use [FromQuery], [FromBody], [FromRoute] explicitly
  • Add /// <summary> XML docs on endpoints for Swagger UI descriptions

CORS (ASP.NET Core)

builder.Services.AddCors(o => o.AddPolicy("Default", p =>
    p.WithOrigins("http://localhost:5173", "https://app.example.com")
     .AllowAnyHeader()
     .AllowAnyMethod()
     .AllowCredentials()));
  • Never AllowAnyOrigin() in production
  • Always pair with AllowCredentials() when using Auth0 cookies

Rate Limiting

Use ASP.NET Core rate limiting middleware for public or expensive endpoints:

builder.Services.AddRateLimiter(o =>
{
    o.AddFixedWindowLimiter("api", opt =>
    {
        opt.Window = TimeSpan.FromMinutes(1);
        opt.PermitLimit = 100;
        opt.QueueLimit = 0;
    });
});

API Design Checklist

Before shipping any new endpoint:

  • Correct HTTP method and status codes
  • Wrapped in ApiResponse<T> or PagedResponse<T>
  • [Authorize] applied (or explicit [AllowAnonymous] with justification)
  • CancellationToken propagated
  • Input validation with clear error messages
  • ProducesResponseType attributes for Swagger
  • Consistent naming with existing endpoints

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.