Symfony-hexagonal-skill symfony-api-response

Symfony API response standardization — JSON payload format, exception handling, controllers, REST endpoints, error responses, debug mode. Triggers on: API, endpoint, controller, response, error handling, JSON, REST, API response, exception subscriber, HTTP

install
source · Clone the upstream repo
git clone https://github.com/aligundogdu/symfony-hexagonal-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aligundogdu/symfony-hexagonal-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/symfony-api-response" ~/.claude/skills/aligundogdu-symfony-hexagonal-skill-symfony-api-response && rm -rf "$T"
manifest: skills/symfony-api-response/SKILL.md
source content

Symfony API Response Standard

You are an expert in building standardized REST APIs within Symfony hexagonal architecture.

When to Activate

  • User creates API endpoints or controllers
  • User asks about response format or error handling
  • User needs exception handling for APIs
  • User mentions REST, JSON, or API design

Standard JSON Payload

ALL API responses use this format:

{
    "result": null,
    "error": null,
    "extra": null,
    "status": 200
}
FieldTypeDescription
result
mixed
Success data (null on error)
error
?object
Error details (null on success)
extra
?object
Metadata: pagination, debug info
status
int
HTTP status code

Success Response

{
    "result": {"id": "uuid-123", "name": "John"},
    "error": null,
    "extra": null,
    "status": 200
}

Error Response

{
    "result": null,
    "error": {"code": "USER_NOT_FOUND", "message": "User not found"},
    "extra": null,
    "status": 404
}

Debug Mode (APP_DEBUG=true)

{
    "result": null,
    "error": {"code": "INTERNAL_ERROR", "message": "Something went wrong"},
    "extra": {"debug": {"exception": "...", "trace": "..."}},
    "status": 500
}

Controller Pattern

Controllers are thin — dispatch to buses only:

namespace App\Presentation\{Module}\API;

use App\Presentation\Shared\ApiResponseTrait;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/api/{module}')]
final class {Entity}Controller
{
    use ApiResponseTrait;

    public function __construct(
        private readonly MessageBusInterface $commandBus,
        private readonly MessageBusInterface $queryBus,
    ) {
    }

    #[Route('', methods: ['POST'])]
    #[IsGranted('ROLE_...')] // ALWAYS include
    public function create(Request $request): JsonResponse
    {
        // 1. Parse input
        // 2. Create command
        // 3. Dispatch to command bus
        // 4. Return success response
    }
}

References

See

references/
for detailed guides:

  • payload-schema.md
    — ApiResponseTrait, response helpers
  • exception-handling.md
    — ExceptionSubscriber, error mapping