Mojolicious-Plugin-Fondation-OpenAPI

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

# NAME

Mojolicious::Plugin::Fondation::OpenAPI - OpenAPI specification generator and runtime validator for Fondation applications

# VERSION

version 0.05

# SYNOPSIS

    # In myapp.conf
    'Fondation::OpenAPI' => {
        backend => 'main',
        schemas => {
            User => {
                columns => {
                    password => {
                        writeOnly => 1,
                        create    => { required => 1 },
                        update    => { required => 0 },
                    },
                },
            },
        },
    }

    # Optional: disable the client-side validators.js rules
    'Fondation::OpenAPI' => {
        no_validator_js => 1,
    }

    # CLI
    $ myapp.pl openapi generate
    $ myapp.pl openapi generate -y
    $ myapp.pl openapi generate --output custom.json

# DESCRIPTION

This plugin provides the `openapi generate` command to produce an
OpenAPI 3.0.3 specification from DBIx::Class sources. At runtime,
`fondation_finalyze` loads the generated `share/openapi.json` via
[Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI) for request validation and adds
Swagger UI routes in development mode.

# CONFIGURATION

## Plugin config

    'Fondation::OpenAPI' => {
        backend => 'main',          # optional -- falls back to DBIx::Async default
        schemas => { ... },         # optional -- column overrides
        no_validator_js => 0,       # optional -- default 0 (client validation on)
    }

### `no_validator_js`

When set to `1`, `openapi generate` still writes `public/js/validators.js`
but the generated `validate()` function accepts everything
(`return { valid: true, errors: [] }`). Server-side OpenAPI validation is
unaffected. Use it to rely solely on server validation (e.g. during testing).

Re-enable client validation by setting it back to `0` (or removing the key)
and regenerating. The same setting is exposed as a boolean parameter in the
plugin's `fondation_meta` `setup` block (default `0`).

### `pattern` in column overrides

Column `pattern` (like `minLength`, `maxLength`, `format`...) is a flat
key accepted both in `extra-`{openapi}> (DBIx Result classes) and in the
`schemas` config override. Patterns MUST be authored in ECMA-262 dialect:
the same regex is used by JSON::Validator server-side (Perl) and by
`new RegExp()` in the generated validators.js. Avoid Perl-only constructs
(`\z`, `\A`, POSIX classes, variable lookbehind, ...).

## Backend resolution

The backend name is resolved in this order:

- 1. OpenAPI's own `backend` config
- 2. DBIx::Async's `default_backend` config key
- 3. First backend in DBIx::Async's `backends` array

## Schema config override

Any column property can be overridden via `schemas` without modifying
DBIx Result classes. See [Mojolicious::Plugin::Fondation::OpenAPI::Command::openapi](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AFondation%3A%3AOpenAPI%3A%3ACommand%3A%3Aopenapi)
for the full list of supported keys.

## x-auth config override

Permission annotations on CRUD endpoints can be overridden via `x_auth`
in the `schemas` config. The default convention is
`{moniker_lc}_{operation}` (e.g., `user_create`, `group_list`).

    'Fondation::OpenAPI' => {
        schemas => {
            User => {
                x_auth => {
                    create => {
                        permissions => ['admin_create_user'],
                        groups      => ['admins'],
                    },
                    list => {
                        permissions => [],   # public endpoint
                    },
                },
            },
        },
    }

Overrides replace the default entirely. An empty `permissions` array
makes the endpoint public (no `x-auth` in the generated spec).
Additional constraint keys (`groups`, `features`, etc.) are translated
into `requires()` route conditions at startup via the `openapi_routes_added` hook.

## openapi\_exclude in plugin `fondation_meta`

Plugins can declare tables that should be excluded from the generated

README.md  view on Meta::CPAN


**Design:** The mechanism lives in plugin `fondation_meta` rather than
in the OpenAPI plugin config because the plugin that owns the table
knows best whether it should be exposed. This follows the Fondation
principle of self-contained bricks — the OpenAPI plugin only reads
what other plugins declare.

# DEPENDENCIES

This plugin requires [Fondation::Model::DBIx::Async](https://metacpan.org/pod/Fondation%3A%3AModel%3A%3ADBIx%3A%3AAsync).

Transitively, it depends on [Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI) >= 5.12,
which requires [JSON::Validator](https://metacpan.org/pod/JSON%3A%3AValidator) >= 5.17.

## Perl 5.40 Incompatibility

On Perl >= 5.40, [Net::IDN::Encode](https://metacpan.org/pod/Net%3A%3AIDN%3A%3AEncode) (a dependency of JSON::Validator
5.17+) fails to compile because its XS code calls `uvuni_to_utf8_flags`,
removed from the Perl C API in 5.40. This cascades:

    Net::IDN::Encode → compile FAIL (Perl ≥ 5.40)
      → JSON::Validator 5.17+ → blocked by cpanm
        → Mojolicious::Plugin::OpenAPI 5.12 → blocked

**Workaround on Debian:** the `libnet-idn-encode-perl` package provides
a pre-compiled version that works on Perl 5.40:

    apt install libnet-idn-encode-perl

# COMMANDS

## openapi generate

Generates `share/openapi.json` and `public/js/validators.js` from
DBIx::Class sources discovered via the configured backend.

Options: `-y` (overwrite without prompt), `--output` (custom path).

# RUNTIME

On startup (`fondation_finalyze`), if `share/openapi.json` exists it
is loaded via [Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI) for request validation.
`x-auth` permissions and groups are translated into route-level
`requires('fondation.perm')` and `requires('fondation.group')`
conditions via the `openapi_routes_added` hook, unifying protection
with HTML routes.
Swagger UI routes (`/swagger` and `/openapi.json`) are added in
development mode. If the spec is missing, a warning is logged and
startup continues.

# OUTPUT FILES

- `share/openapi.json`

    OpenAPI 3.0.3 specification with API Base schemas, contextual
    projections (only when different), and CRUD paths. Committed to the
    application repository.

- `public/js/validators.js`

    Client-side form validation via `FondationValidators.validate()`.
    Consumed by [Fondation::Asset](https://metacpan.org/pod/Fondation%3A%3AAsset) bundles. Committed to the application
    repository.

Always run `openapi generate` before `asset generate`.

# SEE ALSO

[Mojolicious::Plugin::Fondation::OpenAPI::Command::openapi](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AFondation%3A%3AOpenAPI%3A%3ACommand%3A%3Aopenapi),
[Fondation::Model::DBIx::Async](https://metacpan.org/pod/Fondation%3A%3AModel%3A%3ADBIx%3A%3AAsync),
[Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI)

# AUTHOR

Daniel Brosseau <dab@cpan.org>

# COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Daniel Brosseau.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.



( run in 0.487 second using v1.01-cache-2.11-cpan-ad19def0cd9 )