agentsclimarketplace

Api design

Skill Valossa515/sdd/skills/shared/api-design

REST API conventions applicable to both Spring Boot and .NET projects. Covers URL structure, HTTP verbs, status codes, pagination, versioning, and OpenAPI.From its SKILL.md

Install
npx -y skills add Valossa515/sdd --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

  • 1 stars1 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.

SKILL.md

4.4 KB, as published. Nobody here has run it

API Design — Shared Conventions

Apply these conventions regardless of stack (Spring Boot or .NET).

URL Structure

/api/{version}/{resource}
/api/v1/orders
/api/v1/orders/{id}
/api/v1/orders/{orderId}/items
/api/v1/orders/{orderId}/items/{itemId}

Rules:

  • Always plural nouns: /orders not /order
  • Kebab-case for multi-word resources: /order-items
  • No verbs in URLs: /orders/{id}/cancel not /cancelOrder/{id}
  • Actions as sub-resources or using specific verbs: POST /orders/{id}/cancellations

HTTP Verbs & Status Codes

OperationVerbSuccess CodeNotes
List allGET200Always return array, never null
Get oneGET200 / 404404 if not found
CreatePOST201 + Location headerBody = created resource
Full updatePUT200Replace entire resource
Partial updatePATCH200Only update provided fields
DeleteDELETE204No body
Long actionPOST202 AcceptedFor async operations

Pagination

Always paginate list endpoints. Use cursor-based for large datasets, offset for simple cases.

Offset Pagination (default)

GET /api/v1/orders?page=0&size=20&sort=createdAt,desc
{
  "data": [...],
  "pagination": {
    "page": 0,
    "size": 20,
    "totalElements": 150,
    "totalPages": 8,
    "hasNext": true,
    "hasPrevious": false
  }
}

Cursor Pagination (for feeds, timelines)

GET /api/v1/orders?cursor=eyJpZCI6MTAwfQ&limit=20
{
  "data": [...],
  "nextCursor": "eyJpZCI6ODB9",
  "hasMore": true
}

Error Responses

Use RFC 7807 Problem Details for all errors.

{
  "type": "https://api.yourapp.com/errors/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "One or more fields are invalid",
  "instance": "/api/v1/orders",
  "errors": {
    "customerId": ["CustomerId is required"],
    "items": ["Order must have at least one item"]
  }
}

Status code guide:

  • 400 Bad Request — malformed syntax, invalid JSON
  • 401 Unauthorized — not authenticated
  • 403 Forbidden — authenticated but not authorized
  • 404 Not Found — resource doesn't exist
  • 409 Conflict — state conflict (e.g., already confirmed)
  • 422 Unprocessable Entity — validation errors (business rules, field errors)
  • 429 Too Many Requests — rate limiting
  • 500 Internal Server Error — unexpected server error

API Versioning

Use URL versioning (simplest, most explicit):

/api/v1/orders   ← stable
/api/v2/orders   ← new version with breaking changes
  • Keep v1 alive for at least 12 months after v2 launch
  • Document deprecated versions in OpenAPI with deprecated: true
  • Return Sunset header on deprecated endpoints

OpenAPI / Swagger

Always document with OpenAPI 3.0+.

Required for every endpoint:

  • Summary and description
  • All possible response codes
  • Request/response schema
  • Tag grouping by resource

Spring Boot:

@Operation(summary = "Get order by ID")
@ApiResponses({
    @ApiResponse(responseCode = "200", description = "Order found",
        content = @Content(schema = @Schema(implementation = OrderResponse.class))),
    @ApiResponse(responseCode = "404", description = "Order not found",
        content = @Content(schema = @Schema(implementation = ProblemDetail.class)))
})

.NET:

[ProducesResponseType(typeof(OrderResponse), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]

Request/Response Conventions

  • Always accept and return JSON (Content-Type: application/json)
  • Use ISO 8601 for dates: "2024-01-15T10:30:00Z" (always UTC)
  • Use UUID for IDs, never sequential integers exposed in URLs
  • Never return null arrays — return empty [] instead
  • Avoid nested response wrappers like { "data": { ... }, "success": true } — just return the resource directly for success, RFC 7807 for errors

CORS

Configure explicitly — never use wildcard * in production.

Access-Control-Allow-Origin: https://yourfrontend.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type

Keep looking

Skills are one crate of 627,801. 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.