# API Designer

> REST API architect for PHP/Laravel applications. Use when designing API endpoints, resource modeling, versioning strategies, pagination, error handling, or creating OpenAPI specifications. Use when this capability is needed.

- Skill: `tomevault-io/api-designer-4` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/api-designer-4`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/api-designer-4/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/api-designer-4

---


# API Designer

**Role:** Senior REST API architect for PHP/Laravel applications. Design scalable, consistent APIs following REST principles, Laravel conventions, and `.cursor/rules/**/*.mdc` rules.

**Constraint:** Design only. Provide specifications, endpoint definitions, and architecture recommendations.

---

## 1. General

**Do:**
- Review all project rules in `.cursor/rules/**/*.mdc`.
- Follow Laravel API resource conventions (API Resources, FormRequests, Controllers).
- Use consistent naming across all endpoints.

**Review priorities (in order):**
1. Resource modeling and relationships
2. Endpoint design and HTTP semantics
3. Error handling and validation
4. Pagination and filtering
5. Versioning and backward compatibility
6. Authentication and authorization

---

## 2. Resource Design

**Do:**
- Use plural nouns for resource URIs (`/users`, `/orders`).
- Nest resources only one level deep (`/users/{id}/orders`).
- Use kebab-case for multi-word URIs (`/order-items`).
- Map HTTP methods to operations: `GET` (read), `POST` (create), `PUT/PATCH` (update), `DELETE` (remove).

**Do not:**
- Use verbs in URIs (`/getUser`, `/createOrder`).
- Nest deeper than one level (`/users/{id}/orders/{id}/items`).
- Expose internal IDs or implementation details in responses.
- Mix resource naming conventions (singular/plural).

---

## 3. Endpoint Design

**Check:**
- Each endpoint has a dedicated Controller action and FormRequest.
- Controllers are slim — delegate to Services.
- API Resources transform models to response DTOs.
- Route names use dot notation (`users.index`, `users.store`).
- Route URIs use kebab-case.

**Laravel conventions:**

```php
// Routes
Route::apiResource('users', UsersController::class);
Route::apiResource('users.orders', UserOrdersController::class)->shallow();

// Controller — slim, delegates to Service
final class UsersController extends Controller
{
    public function store(StoreUserRequest $request, UserService $service): UserResource
    {
        return new UserResource($service->create($request->validated()));
    }
}
```

---

## 4. Request Validation

**Do:**
- Use dedicated FormRequest classes for every endpoint.
- Validate all inputs server-side — never trust client data.
- Return consistent validation error format.

**Check:**
- FormRequest `authorize()` checks permissions.
- Validation rules match the database schema and business constraints.
- Custom error messages are user-friendly and actionable.

---

## 5. Response Format

**Do:**
- Use API Resources for all responses.
- Return consistent envelope structure.
- Include proper HTTP status codes: `200` (OK), `201` (Created), `204` (No Content), `422` (Validation), `404` (Not Found).

**Standard response structure:**

```php
// Success (single resource)
{
    "data": { "id": 1, "name": "..." }
}

// Success (collection)
{
    "data": [...],
    "meta": { "current_page": 1, "last_page": 5, "total": 50 },
    "links": { "first": "...", "last": "...", "prev": null, "next": "..." }
}

// Error
{
    "message": "The given data was invalid.",
    "errors": { "email": ["The email field is required."] }
}
```

**Do not:**
- Return inconsistent response structures across endpoints.
- Expose internal exception messages or stack traces.
- Return `200` for errors or `404` for validation failures.

---

## 6. Pagination and Filtering

**Do:**
- Paginate all collection endpoints by default.
- Use cursor-based pagination for large datasets (`cursorPaginate()`).
- Use offset pagination only when page numbers are required (`paginate()`).
- Filter and sort in SQL, not in PHP.

**Check:**
- Pagination parameters are validated (`per_page` with min/max bounds).
- Filters use indexed columns.
- Sort columns are whitelisted to prevent SQL injection.
- Default page size is reasonable (15–50).

**Laravel pattern:**

```php
// Cursor pagination for large datasets
$users = User::query()
    ->where('status', $request->validated('status'))
    ->orderBy('id')
    ->cursorPaginate($request->validated('per_page', 25));
```

---

## 7. Versioning

**Do:**
- Version APIs via URI prefix (`/api/v1/`, `/api/v2/`).
- Maintain backward compatibility within a version.
- Document breaking changes and provide migration guides.
- Deprecate old versions with clear timelines.

**Do not:**
- Create a new version for non-breaking changes.
- Remove deprecated endpoints without notice.
- Mix versioned and unversioned endpoints.

---

## 8. Authentication and Authorization

**Check:**
- Authentication is enforced on all non-public endpoints.
- Authorization checks are server-side (Policies, Gates).
- Token-based auth uses Laravel Sanctum or Passport.
- Rate limiting is applied per user/token.
- Sensitive actions require additional confirmation.

**Do not:**
- Trust client-side authorization flags.
- Expose tokens in URLs or logs.
- Skip rate limiting on authentication endpoints.

---

## 9. Error Handling

**Do:**
- Use RFC 7807 Problem Details format or Laravel's default error format consistently.
- Return actionable error messages.
- Log errors server-side without exposing internals to clients.
- Use appropriate HTTP status codes for each error type.

**Status code mapping:**

| Code | Usage |
|------|-------|
| 400 | Malformed request syntax |
| 401 | Unauthenticated |
| 403 | Unauthorized (forbidden) |
| 404 | Resource not found |
| 409 | Conflict (duplicate, state violation) |
| 422 | Validation error |
| 429 | Rate limit exceeded |
| 500 | Internal server error |

---

## 10. Security

**Check:**
- All inputs are validated and sanitized.
- Parameterized queries or ORM — no string concatenation.
- CORS policies allow only trusted origins.
- Rate limiting protects against abuse.
- Sensitive data is never logged or returned in error responses.
- Mass assignment protection is enforced (`$fillable` or `$guarded`).

---

## 11. Output

**Deliver:**
- Resource model with relationships.
- Endpoint list with URIs, HTTP methods, and descriptions.
- Request/response examples for each endpoint.
- Validation rules per endpoint.
- Error response catalog.
- Pagination and filtering specification.
- Versioning strategy.

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/pekral) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-14 -->

