# Schwager

Namespace Chevere\Schwager

The Schwager package provides an API spec generator for the Router package. The complementary package chevere/schwager-html (opens new window) enables to create an HTML representation for Schwager.

💡 Schwager introduction

Read Schwager API (opens new window) and Schwager HTML (opens new window) at Rodolfo's blog for a compressive introduction to this package.

# Installing

Schwager is available through Packagist (opens new window) and the repository source is at chevere/schwager (opens new window).

composer require chevere/schwager

# Specification

The Schwager API spec has the following general format:

    "api": "<API>",
    "name": "<NAME>",
    "version": "<VERSION>",
    "servers": [
            "url": "<SERVER_URL>",
            "description": "<SERVER_DESCRIPTION>"
    "paths": {
        "<PATH>": {
            "name": "<PATH_NAME>",
            "group": "<PATH_GROUP>",
            "regex": "<PATH_REGEX>",
            "variables": {
                "<VARIABLE>": {
                    "type": "string",
                    "description": "<VARIABLE_DESCRIPTION>",
                    "regex": "<VARIABLE_REGEX>"
            "endpoints": {
                "<METHOD>": {
                    "description": "<ENDPOINT_DESCRIPTION>",
                    "request" : {
                        "headers": {
                        "query": {
                        "body":  {

                    "responses": {
                        "<STATUS_CODE>": [
                                "context": "<RESPONSE_CONTEXT>",
                                "headers": {
                                "body": {

# Identification

Properties for API identification.

  • <API>
  • <NAME>

# Servers

The servers array indicate the server(s) available for interacting with the API.


# Paths

The paths property contains a map for URI paths.

  • <PATH>

For each path it takes the following properties:


# Variables

Path variables are mapped by name within the variables property.


For each variable it provides the following properties. Path variables are always of type string.


# Endpoints

Path endpoints are mapped by HTTP method name within the endpoints property.

  • <METHOD>

# Schemas

The body schema *_BODY_SCHEMA describes the payload body. It supports parameter schema of any type.

The query schema REQUEST_QUERY_SCHEMA describes the request query string. It supports an array of strings.

# Request

Request metadata is taken from the Request attribute


# Responses

Endpoint responses are mapped by status code within the responses property. Response metadata is taken from the Response attribute


Schwager supports multiple responses for the same status code. For each response it provides the following properties:


# Creating API spec

To create an API spec pass an object implementing RouterInterface and a DocumentSchema. Optionally, you can provide one or more ServerSchema objects.

use Chevere\Schwager\DocumentSchema;
use Chevere\Schwager\ServerSchema;
use Chevere\Schwager\Spec;
use function Chevere\Router\router;

$router = router();
$document = new DocumentSchema(
    api: 'chevere',
    name: 'Chevere API',
    version: '1.0.0'
$server = new ServerSchema(
    url: 'https://localhost:8080',
    description: 'Development server'
$spec = new Spec($router, $document, $server);

Use method toArray to get the printer-ready array needed to export to other formats.

$array = $spec->toArray();

# Filtering result

The arrayFilter* functions provided by the Standard component enable to modify and/or filter the generated API spec. This is useful to remove null values, empty strings and context-aware redundant information.

For example to recursive filter the array by value $v and key $k:

use function Chevere\Standard\arrayFilterBoth;

$array = arrayFilterBoth($spec->toArray(), function ($v, $k) {
    return match (true) {
        $v === null => false,
        $v === [] => false,
        $v === '' => false,
        $k === 'required' && $v === true => false,
        $k === 'regex' && $v === '^.*$' => false,
        $k === 'body' && $v === [
            'type' => 'array#map',
        ] => false,
        default => true,

The match used in the code above indicates that for every key value pair:

  • Remove if the value is null
  • Remove if the value is []
  • Remove if the value is empty string
  • Remove if the key is required and value is true
  • Remove if the key is regex and value is ^.*$
  • Remove if the key is body and value is ['type' => 'array#map']
  • (default) Keep as is

For cases 1,2,3 the removal is for empty values while for cases 4,5,6 is because of redundant info.

# Export

Use the built-in Filesystem component to store the converted array with native json_encode (opens new window) as a JSON file.

use function Chevere\Filesystem\fileForPath;

$json = json_encode($array, JSON_PRETTY_PRINT);
$file = fileForPath(__DIR__ . '/api.json');

🪄 A PHP array can be converted to any format including YAML (opens new window), XML (opens new window) and more.