[![Build Status](https://img.shields.io/github/actions/workflow/status/zircote/swagger-php/build.yml?branch=master)](https://github.com/zircote/swagger-php/actions?query=workflow:build)
[![Total Downloads](https://img.shields.io/packagist/dt/zircote/swagger-php.svg)](https://packagist.org/packages/zircote/swagger-php)
[![License](https://img.shields.io/badge/license-Apache2.0-blue.svg)](LICENSE)

# swagger-php

Generate interactive [OpenAPI](https://www.openapis.org) documentation for your RESTful API
using [PHP attributes](https://www.php.net/manual/en/language.attributes.overview.php) (preferred) or
[doctrine annotations](https://www.doctrine-project.org/projects/annotations.html) (requires additional
`doctrine/annotations` library).

See the [documentation website](https://zircote.github.io/swagger-php/guide/using-attributes.html) for supported
attributes and annotations.

**Annotations are deprecated and may be removed in a future release of swagger-php.**

## Features

- Compatible with the OpenAPI **3.0**, **3.1** and **3.2** specification.
- Extracts information from code and existing phpdoc comments.
- Can be used programmatically or via command-line tool.
- Error reporting (with hints, context).
- 🧪 **Spec attributes pipeline (beta)** — a new processing mode with typed DTOs, grouped augmenters, and version-aware compilers.

## OpenAPI version support

`swagger-php` can generate specs for **OpenAPI 3.0.0**, **OpenAPI 3.1.0** and **OpenAPI 3.2.0**.
Classic mode defaults to `3.0.0`, spec and hybrid mode to `3.1.0`.

The command line option `--version` selects a different version; programmatically, use
`Builder::setVersion()`.

## Requirements

`swagger-php` requires at least **PHP 8.2**.

## Installation (with [Composer](https://getcomposer.org))

```shell
composer require zircote/swagger-php
```

For cli usage from anywhere, install swagger-php globally and add Composer's global binary directory
(`composer global config bin-dir --absolute`) to your PATH, so the `openapi` executable can be located by
your system.

```shell
composer global require zircote/swagger-php
```

### doctrine/annotations

As of version `4.8` the [doctrine annotations](https://www.doctrine-project.org/projects/annotations.html) library **is
optional** and **no longer installed by default**.

If your code uses doctrine annotations you will need to install that library manually:

```shell
composer require doctrine/annotations
```

## Usage

Use OpenAPI attributes to add metadata to your classes, methods and other structural PHP elements.

```php

use OpenApi\Attributes as OAT;

#[OAT\Info(title: 'My First API', version: '0.1')]
class MyApi
{
    #[OAT\Get(path: '/api/resource.json')]
    #[OAT\Response(response: '200', description: 'An example resource')]
    public function getResource()
    {
        // ...
    }
}
```

Visit the [Documentation website](https://zircote.github.io/swagger-php/) for
the [Getting started guide](https://zircote.github.io/swagger-php/guide) or look at
the [examples directory](docs/examples) for more examples.

### 🧪 Spec Attributes (Beta)

*Available since 6.5.0*

A new processing mode using typed attributes from the `OpenApi\Spec` namespace:

```php
use OpenApi\Spec as OA;

#[OA\OpenApi(version: '3.1.0')]
#[OA\Info(title: 'My API', version: '1.0')]
class MyApi
{
    #[OA\Operation\Get(path: '/api/resource')]
    #[OA\Response(response: 200, description: 'An example resource')]
    public function getResource() {}
}
```

```php
$result = (new \OpenApi\Builder())
    ->setMode(\OpenApi\Builder\Mode::SPEC)
    ->addSource('src/')
    ->build();
```

**Hybrid mode** works with your existing `OpenApi\Attributes` code — no changes needed. It runs the classic scanner
but uses the new augmenter pipeline and version-aware compilers, which are easier to extend.
If you'd like to help test the new pipeline, switching to hybrid is the easiest way:

```php
$result = (new \OpenApi\Builder())
    ->setMode(\OpenApi\Builder\Mode::HYBRID)
    ->addSource('src/')
    ->build();
```

Or from the CLI: `./vendor/bin/openapi src/ --mode hybrid`

See the [Spec Attributes guide](https://zircote.github.io/swagger-php/guide/spec-attributes) and
[Processing Modes](https://zircote.github.io/swagger-php/guide/modes) for full documentation.

### Usage from PHP

Generate always-up-to-date documentation.

```php
<?php
require("vendor/autoload.php");
$result = (new \OpenApi\Builder())
    ->addSource(['/path/to/project'])
    ->build();
header('Content-Type: application/x-yaml');
echo $result->toYaml();
```

Details on how to generate OpenApi specifications can be found
in the [generate reference](https://zircote.github.io/swagger-php/guide/generating-openapi-documents).

### Usage from the Command Line Interface

The `openapi` command line interface can be used to generate the documentation to a static yaml/json file.

```shell
./vendor/bin/openapi --help
```

## Automatic type resolution

As of version 6, resolving of types is done using the `TypeInfoTypeResolver` class. It uses the `symfony/type-info`
library under the hood which allows handling of complex types.

With this change, `swagger-php` supports all available native type-hints and also complex generic type-hints via phpdoc
blocks.
This simplifies the definition of schemas.

For example, the following two examples are now equivalent:

```php
class MyClass
{
    #[OAT\Property(items: new OAT\Items(oneOf: [
        new OAT\Schema(type: SchemaOne::class),
        new OAT\Schema(type: SchemaTwo::class),
    ]))]
    public array $values;
}
```

```php
class MyClass
{
    /**
     * @var list<SchemaOne|SchemaTwo>
     */
    public array $values;
}
```

If this is not desired, the `LegacyTypeResolver` can be used to preserve the old behaviour of version 5.
The `LegacyTypeResolver` is deprecated and will be removed in a future release.

## [Contributing](CONTRIBUTING.md)

## More on OpenApi & Swagger

- https://swagger.io
- https://www.openapis.org
- [OpenApi Documentation](https://swagger.io/docs/)
- [OpenApi Specification](http://swagger.io/specification/)
- [Related projects](docs/related-projects.md)
