← API

API FEATURE

Schema Discovery

A machine-facing API should explain its own shape and let you exercise the contract without leaving the demo.

Feature Guide

A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.

What this does

Schema Discovery turns the raw `_schema` endpoint into a small interactive API console. The page still talks to the real live Semitexa routes.

How it works

The human-facing demo page is a normal DemoFeatureResource, but each operation button issues a fetch() call against the external API endpoints under `/demo/api/...`. The schema contract and example responses are preloaded server-side so the page reads like documentation before you click anything.

Why it matters

This is closer to how people evaluate APIs in practice: they want to poke the contract, compare responses, and confirm the system shape without wiring Postman first.

Key concepts

_schema
Machine-facing schema endpoint returning JSON Schema for the product contract.
application/schema+json
Explicit media type for tooling that consumes JSON Schema documents.
Sparse fieldset
A client asks for only the fields it needs via `fields=...`.

Schema Discovery

Mini Swagger for the live Semitexa API

Click any operation below. The panel on the right performs a real request against the current `/demo/api/...` endpoint and shows the exact response body.

Live response

GET schema

200 application/json

Request headers

{
    "Accept": "application\/json"
}
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "/demo/api/v1/products/_schema",
    "title": "Semitexa Demo Product",
    "type": "object",
    "required": [
        "slug",
        "name",
        "price"
    ],
    "properties": {
        "slug": {
            "type": "string",
            "description": "Stable product slug used by the demo API detail route."
        },
        "name": {
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0
        },
        "description": {
            "type": [
                "string",
                "null"
            ]
        },
        "status": {
            "type": "string",
            "enum": [
                "active",
                "sale",
                "archived"
            ]
        },
        "category": {
            "type": [
                "object",
                "null"
            ],
            "required": [
                "slug",
                "name"
            ],
            "properties": {
                "slug": {
                    "type": "string"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "rating": {
            "type": "number",
            "minimum": 0,
            "maximum": 5
        },
        "reviewCount": {
            "type": "integer",
            "minimum": 0
        },
        "reviews": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "user",
                    "rating",
                    "body"
                ],
                "properties": {
                    "user": {
                        "type": "string"
                    },
                    "rating": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "body": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            }
        },
        "links": {
            "type": "object",
            "properties": {
                "self": {
                    "type": "string"
                },
                "collection": {
                    "type": "string"
                }
            }
        }
    }
}
#[ExternalApi] application/schema+json JSON Schema live explorer

Verified against Semitexa Ultimate 2026.09.19.1020

Schema Discovery

A machine-facing API should explain its own shape and let you exercise the contract without leaving the demo.

How it works

The product API exposes a dedicated _schema endpoint that returns the full JSON Schema for the product representation. The endpoint responds to both application/json and application/schema+json Accept headers, so machine tooling and human browsers get the same document at the right content type. The schema explorer on this page exercises the live contract: schema endpoint, sparse fieldset detail, and expanded graph with category and review data.

Why this matters

API clients should not have to reverse-engineer the response shape from examples. A schema endpoint gives SDK generators, validation layers, and developer tooling a single source of truth. Responding to application/schema+json makes the endpoint machine-discoverable through standard tooling without a separate OpenAPI pipeline.

© Jeff Sickel: "Deleted code is debugged code."

Schema Discovery Handler Application entry point
<?phpdeclare(strict_types=1);namespace App\Application\Handler\Api;use App\Application\Payload\Api\ApiSchemaDiscoveryPayload;use App\Application\Resource\Page\ApiSchemaPageResource;use App\Domain\Api\SchemaRegistryInterface;use Semitexa\Core\Attribute\AsPayloadHandler;use Semitexa\Core\Attribute\InjectAsReadonly;use Semitexa\Core\Contract\TypedHandlerInterface;#[AsPayloadHandler(payload: ApiSchemaDiscoveryPayload::class, resource: ApiSchemaPageResource::class)]final class ApiSchemaDiscoveryHandler implements TypedHandlerInterface{    #[InjectAsReadonly]    protected SchemaRegistryInterface $schemaRegistry;    public function handle(ApiSchemaDiscoveryPayload $payload, ApiSchemaPageResource $resource): ApiSchemaPageResource    {        return $resource->fromSchema($this->schemaRegistry->describe());    }}

Contract Notes

What this explorer is proving

Operation What changes Why it matters
GET /demo/api/v1/products/_schema Raw JSON schema contract for the product representation. Consumers can validate the contract before writing integration code.
GET /demo/api/v1/products/_schema Same contract, explicit schema media type for machine tooling. Consumers can validate the contract before writing integration code.
GET /demo/api/v1/products/wireless-headphones?fields=slug,name,price Sparse fieldset proving the contract can be trimmed intentionally. Consumers can validate the contract before writing integration code.
GET /demo/api/v1/products/wireless-headphones?profile=full&expand=category,reviews Expanded graph with review data for internal dashboards and rich clients. Consumers can validate the contract before writing integration code.

How it works

The human-facing demo page is a normal DemoFeatureResource, but each operation button issues a fetch() call against the external API endpoints under `/demo/api/...`. The schema contract and example responses are preloaded server-side so the page reads like documentation before you click anything.

Why it matters

This is closer to how people evaluate APIs in practice: they want to poke the contract, compare responses, and confirm the system shape without wiring Postman first.

Key concepts

_schema
Machine-facing schema endpoint returning JSON Schema for the product contract.
application/schema+json
Explicit media type for tooling that consumes JSON Schema documents.
Sparse fieldset
A client asks for only the fields it needs via `fields=...`.

Support Semitexa
Built for developers who prefer control over magic. Your support helps keep it fast, open, and evolving.

Donate via PayPal