Looking to hire Laravel developers? Try LaraJobs

laravel-bruno-generator maintained by shahghasiadil

Description
Generate Bruno API collections from Laravel routes with automatic request body inference and environment support
Last update
2026/08/19 13:33 (dev-main)
License
Downloads
4 888

Comments
comments powered by Disqus

Laravel Bruno Generator

Latest Version on Packagist Total Downloads

Generate Bruno API collections from Laravel routes.

This package analyzes your Laravel application's routes and generates a ready-to-use Bruno collection, complete with request bodies inferred from FormRequests, authentication configuration, environment files, and more.

Installation

You can install the package via composer:

composer require shahghasiadil/laravel-bruno-generator --dev

Publish the config file:

php artisan vendor:publish --tag=bruno-generator-config

Quick Start

Generate a collection:

php artisan bruno:generate

Default output:

bruno/collections/Laravel-API/

Open that folder in Bruno using Open Collection.

Features

  • One-command generation from Laravel routes
  • FormRequest body inference
  • Route filtering (middleware, prefix, include/exclude)
  • Multiple organization strategies (prefix, controller, tag, none)
  • Auth support (none, bearer, basic, oauth2), with protected routes pointing at a shared collection-level auth block (auth: inherit)
  • Real Bruno path parameters (:id + params:path) and query parameters inferred from FormRequest rules, with example values informed by where() route constraints when present
  • Multi-environment generation (Local, Staging, Production by default)
  • Optional docs, tests, and scripts generation
  • .bru and OpenCollection YAML (.yml) output support
  • Deterministic, git-friendly generated files
  • bruno:check drift detection for CI — regenerates in memory and exits non-zero if the committed collection is out of date

Usage

Common commands

Generate with default settings:

php artisan bruno:generate

Generate YAML output:

php artisan bruno:generate --format=yaml

Generate only API routes protected by Sanctum:

php artisan bruno:generate --api-only --middleware=auth:sanctum

Generate with docs and tests:

php artisan bruno:generate --with-docs --with-tests

Preview without writing files:

php artisan bruno:generate --dry-run

Overwrite existing output:

php artisan bruno:generate --force

Clear generated collection:

php artisan bruno:clear

Clear a custom path:

php artisan bruno:clear path/to/collection --force

Check whether the committed collection has drifted from what your routes currently produce (regenerates in memory, writes nothing, exits non-zero on drift — useful as a CI gate):

php artisan bruno:check

bruno:check accepts the same filtering/format options as bruno:generate (--format, --output, --name, --api-only, --prefix, --exclude-prefix, --middleware, --exclude-middleware, --group-by) so you can check the same slice of routes you'd generate. Add --verbose to list which files would be added, changed, or are orphaned on disk.

All generate options

php artisan bruno:generate \
  --format=bru|yaml \
  --output=path/to/output \
  --name="My API" \
  --api-only \
  --prefix=api/v1 \
  --exclude-prefix=admin \
  --middleware=auth:sanctum \
  --exclude-middleware=web \
  --group-by=prefix|controller|tag|none \
  --with-body-inference \
  --with-tests \
  --with-scripts \
  --with-docs \
  --force \
  --dry-run

Configuration

You can control most behavior through .env:

BRUNO_OUTPUT_PATH=bruno/collections
BRUNO_COLLECTION_NAME="Laravel API"
BRUNO_OUTPUT_FORMAT=bru
BRUNO_GROUP_BY=prefix
BRUNO_INFER_BODY=true
BRUNO_AUTH_MODE=bearer

APP_URL=http://localhost:8000
STAGING_URL=https://staging.example.com
PRODUCTION_URL=https://api.example.com

After publishing, full options are available in config/bruno-generator.php.

Key config sections

  • output_path, collection_name, output_format
  • route_discovery for include/exclude rules
  • organization for grouping and sorting
  • request_generation for body/query/header behavior
  • auth for mode and auth middleware detection
  • environments for generated Bruno environments
  • advanced for docs length, tests, scripts, YAML options, request settings

FormRequest Body Inference

When enabled, request bodies are generated from your FormRequest rules.

Example FormRequest rules:

public function rules(): array
{
    return [
        'name' => 'required|string|max:255',
        'email' => 'required|email',
        'age' => 'integer|min:18',
        'is_active' => 'boolean',
        'tags' => 'array',
        'tags.*' => 'string',
    ];
}

Example generated body:

{
  "name": "Name",
  "email": "user@example.com",
  "age": 18,
  "is_active": true,
  "tags": [""]
}

Nested rules like user.name and user.email are also supported.

Other rules that shape the generated example:

  • in:draft,published,archived uses the first listed value (draft)
  • between:5,20 on an integer/numeric field uses the lower bound (5), same as min:
  • A file or image rule on any field switches the whole request to a multipart-form body instead of JSON

Output Formats

Both output formats are supported:

  • bru (default)
  • yaml

Use command flag:

php artisan bruno:generate --format=yaml

Or environment variable:

BRUNO_OUTPUT_FORMAT=yaml

Environments

By default, the package generates:

  • Local
  • Staging
  • Production

Each environment contains values like baseUrl and authToken and can be switched in Bruno.

You can add custom environments (for example Development, QA, UAT) in config/bruno-generator.php.

Secret variables

Variable names listed in secrets.variable_names (authToken by default) are never written to the generated environment file — Bruno manages their real value separately (OS keychain, or AES256 as a fallback), and you set it through Bruno's environment UI after opening the collection. In .bru output this looks like a name-only vars:secret [...] block; in YAML output the variable gets secret: true and an empty value.

Use the array shape to mark a custom variable as secret, or add a description:

'environments' => [
    'Staging' => [
        'baseUrl' => env('STAGING_URL', 'https://staging.example.com'),
        'apiKey' => [
            'value' => env('STAGING_API_KEY', ''),
            'description' => 'API key issued by the staging gateway',
            'secret' => true,
        ],
    ],
],

Descriptions are a Bruno 4 addition; set bruno_compatibility to v3 to omit them if your collection needs to open in an older Bruno.

Generated Structure

Typical output:

bruno/collections/Laravel-API/
  bruno.json
  environments/
    Local.bru
    Staging.bru
    Production.bru
  api/
    ...requests and folders...

Best Practices

  • Use --dry-run before first full generation
  • Keep route filters explicit in larger projects
  • Commit generated collections to track API changes
  • Keep environment URLs in .env
  • Let authToken (and other secrets) stay a secret variable rather than disabling secret: false — its real value never gets written to disk
  • Run php artisan bruno:check in CI to catch a committed collection that's drifted from the routes it was generated from

Testing

Run tests:

composer test

Run static analysis:

composer analyse

Format code:

composer format

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

If you discover any security-related issues, please email adil.shahghasi@gmail.com.

Credits

License

The MIT License (MIT). Please see License File for more information.