hopheartsceo/laravel-postman-exporter

Automatically generate Postman v2.1 collections from your Laravel application routes, controllers, and FormRequest validations.

Maintainers

Package info

github.com/hopheartsceo/Laravel-Postman-Exporter

pkg:composer/hopheartsceo/laravel-postman-exporter

Transparency log

Statistics

Installs: 688

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

v1.6.0 2026-08-16 07:22 UTC

README

Laravel PHP License

Automatically generate Postman Collection v2.1 files and OpenAPI 3.0 specifications from your Laravel application routes, controllers, and FormRequest validations — complete with folder grouping and response examples.

Features

  • Route Scanning — Automatically reads all registered API routes
  • Request Analysis — Extracts validation rules from FormRequest classes and inline $request->validate() calls
  • Context-Aware FormRequests — Evaluates rules with the actual HTTP method, route name, route parameters, and container-injected dependencies
  • API Contract Guard — Detects breaking request and response changes and returns a failing exit code for CI
  • Example Data Generation — Generates realistic sample values based on validation rules and field names
  • Authentication Detection — Automatically adds auth headers based on middleware (Sanctum, Passport, etc.)
  • Folder Grouping — Organizes requests into folders based on route prefixes
  • Response Examples — Extracts response structures from PHPDoc, API Resources, response()->json(), and Eloquent models
  • Response Contract Analysis — Builds OpenAPI schemas from Laravel API Resources, including conditional fields, nested resources, collections, pagination, and top-level metadata
  • Multi-Response Contracts — Captures multiple response branches/status codes and Laravel's default validation 422 contract
  • Response Pipeline Tracing — Statically follows controller, trait, inherited, and static response helpers to discover wrapped payloads and status codes without executing endpoints
  • OpenAPI Support — Export your API as a valid OpenAPI 3.0.3 specification
  • Postman Upload — Optionally upload generated Postman collections directly via the Postman API
  • Artisan Command — Beautiful CLI with progress indicators and colored output

Installation

You can install the package via composer:

composer require hopheartsceo/laravel-postman-exporter --dev

Installation from GitHub (Development)

If you haven't published to Packagist yet, add this to your composer.json:

"repositories": [
    {
        "type": "vcs",
        "url": "https://github.com/hopheartsceo/laravel-postman-exporter"
    }
],
"require": {
    "hopheartsceo/laravel-postman-exporter": "dev-main"
}

Publish the configuration file:

php artisan vendor:publish --tag=postman-exporter-config

Usage

Artisan Command

# Export as Postman Collection (default)
php artisan postman:export

# Export as OpenAPI 3.0 specification
php artisan postman:export --format=openapi

# Custom output path
php artisan postman:export --output=./docs/api-spec.json

# Group routes by prefix (works for both formats)
php artisan postman:export --group-by-prefix

# Include response examples (Postman only currently)
php artisan postman:export --with-responses

# Save the current API contract as a baseline
php artisan postman:check --write-baseline

# Fail when breaking API changes are detected
php artisan postman:check

# Compare against a custom OpenAPI baseline
php artisan postman:check --against=docs/openapi-baseline.json

Facade API

use Hopheartsceo\PostmanExporter\Facades\PostmanExporter;

// Generate Postman Collection (default)
$collection = PostmanExporter::generate();

// Generate OpenAPI spec
$openapi = PostmanExporter::generate('openapi');

// Generate and save to file
$path = PostmanExporter::save('/path/to/collection.json');

// Generate and upload to Postman
$result = PostmanExporter::upload('your-api-key');

Configuration

After publishing, edit config/postman-exporter.php:

Option Type Default Description
base_url string env('APP_URL') Base URL for all requests
default_headers array Accept + Content-Type JSON Default headers on every request
output_path string storage/app/postman-collection.json Default output path
collection_name string App name + " API Collection" Name of the Postman collection
grouping array (see below) Folder grouping configuration
responses array (see below) Response examples configuration
include_web_routes bool false Include non-API routes
postman_api_key string '' Postman API key for uploads
enable_upload bool false Auto-upload after generation

Folder Grouping

Routes are grouped into flat, single-level folders by the first segment of the URI. No nesting is created — every route belongs to exactly one top-level folder.

'grouping' => [
    'enabled'         => true,
    'strategy'        => 'prefix',      // Only 'prefix' strategy supported
    'fallback_folder' => 'general',     // Folder for unprefixed / root routes
],

How it works:

URI Folder
api/users api
api/users/{id} api
auth/login auth
auth/logout auth
status general (fallback)
/{id} general (fallback)
  • The first segment of the URI (explode('/', $uri)[0]) becomes the folder name.
  • Routes whose first segment is empty or a parameter (e.g. {id}) go to the fallback folder.
  • There are no root-level requests — every request lives inside a folder.
  • There are no nested folders — the structure is always flat.

Response Examples

Response examples are extracted automatically from your controller methods and attached to each Postman request item.

'responses' => [
    'enabled'         => true,
    'fallback_status' => 200,
    'fallback_body'   => null,
],

Or enable at export time with the --with-responses flag:

php artisan postman:export --with-responses

Response discovery sources:

The exporter combines distinct HTTP status codes from multiple sources instead of stopping at the first match. When two sources describe the same status, the earlier explicit source wins.

  1. PHPDoc @response — Parses one or more @response tags with optional status codes:

    /**
     * @response 200 {"id": 1, "name": "John Doe"}
     * @response {"data": []}
     */
    public function index() { ... }
  2. API Resource — Detects direct Resource returns and builds response schemas from the Resource's toArray() structure.

  3. Direct Laravel responses — Parses inline response()->json([...], 200) and response()->noContent() returns, including their status codes.

  4. Response Pipeline Tracing — Follows custom $this->helper(...), inherited/trait helpers, and static response helper methods until it reaches response()->json(...) or response()->noContent().

  5. Eloquent Model — Detects return User::find(...) patterns and generates example data from the model's $fillable fields.

  6. Fallback — Uses the configured fallback status and body. By default, the body is null so unknown responses are not documented as fabricated success payloads.

Response pipelines are analyzed statically. Controller endpoints and response helpers are not executed during export or contract checks.

When validation rules are detected, the exporter also adds Laravel's default JSON 422 validation-error contract. This inference is skipped when a FormRequest overrides failedValidation(), and it can be disabled with responses.framework_validation_errors.

Generated response format in Postman:

{
    "response": [
        {
            "name": "Success Response",
            "originalRequest": { "method": "GET", "url": { ... } },
            "status": "OK",
            "code": 200,
            "_postman_previewlanguage": "json",
            "header": [
                { "key": "Content-Type", "value": "application/json" }
            ],
            "body": "{\"id\": 1, \"name\": \"John Doe\"}"
        }
    ]
}

Route Filters

'route_filters' => [
    'include_prefixes'  => [],              // Only include these prefixes
    'exclude_prefixes'  => ['_ignition'],   // Exclude these prefixes
    'include_middleware' => [],              // Only include routes with these middleware
    'exclude_middleware' => [],              // Exclude routes with these middleware
],

Middleware to Headers Map

'middleware_to_headers_map' => [
    'auth:sanctum' => [
        'Authorization' => 'Bearer {{token}}',
    ],
    'auth:api' => [
        'Authorization' => 'Bearer {{token}}',
    ],
],

Example Output

The generated collection follows the Postman Collection v2.1 schema. Folders are flat (single-level) and each request includes response examples:

{
    "info": {
        "name": "My App API Collection",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "item": [
        {
            "name": "api",
            "item": [
                {
                    "name": "users.index",
                    "request": {
                        "method": "GET",
                        "url": {
                            "raw": "{{base_url}}/api/users",
                            "host": ["{{base_url}}"],
                            "path": ["api", "users"]
                        },
                        "header": [
                            { "key": "Accept", "value": "application/json" },
                            { "key": "Authorization", "value": "Bearer {{token}}" }
                        ]
                    },
                    "response": [
                        {
                            "name": "Success Response",
                            "originalRequest": {
                                "method": "GET",
                                "url": {
                                    "raw": "{{base_url}}/api/users",
                                    "host": ["{{base_url}}"],
                                    "path": ["api", "users"]
                                }
                            },
                            "status": "OK",
                            "code": 200,
                            "_postman_previewlanguage": "json",
                            "header": [
                                { "key": "Content-Type", "value": "application/json" }
                            ],
                            "body": "{\"data\": [{\"id\": 1, \"name\": \"John Doe\"}]}"
                        }
                    ]
                }
            ],
            "description": "Routes for api"
        },
        {
            "name": "general",
            "item": [
                {
                    "name": "GET Status",
                    "request": {
                        "method": "GET",
                        "url": {
                            "raw": "{{base_url}}/status",
                            "host": ["{{base_url}}"],
                            "path": ["status"]
                        }
                    },
                    "response": [
                        {
                            "name": "Success Response",
                            "originalRequest": {
                                "method": "GET",
                                "url": {
                                    "raw": "{{base_url}}/status",
                                    "host": ["{{base_url}}"],
                                    "path": ["status"]
                                }
                            },
                            "status": "OK",
                            "code": 200,
                            "_postman_previewlanguage": "json",
                            "header": [
                                { "key": "Content-Type", "value": "application/json" }
                            ],
                            "body": "{\"message\": \"Success\"}"
                        }
                    ]
                }
            ],
            "description": "Routes for general"
        }
    ],
    "variable": [
        { "key": "base_url", "value": "http://localhost" },
        { "key": "token", "value": "your-auth-token-here" }
    ]
}

See examples/sample-collection.json for a full example with multiple folders and response examples.

🧪 Testing

composer test
# or
vendor/bin/phpunit

🏗️ Architecture

Service Responsibility
RouteScannerService Scans Laravel routes via the Router; extracts return types, PHPDoc, and API Resource usage
RequestAnalyzerService Extracts FormRequest/inline validation rules
ValidationParserService Parses validation rules into structured format
ExampleDataGeneratorService Generates realistic sample values
FolderOrganizerService Groups routes into flat, single-level folders by first URI segment
ResponseExtractorService Analyzes controller methods to extract response structures (PHPDoc → API Resource → JSON → Model → Fallback)
ExampleResponseGeneratorService Converts extracted response data into Postman-formatted response arrays
PostmanCollectionBuilderService Builds Postman v2.1 JSON structure with folders and response examples
PostmanUploaderService Uploads collections to Postman API

Requirements

  • PHP 8.1+
  • Laravel 10, 11, or 12

License

MIT License. See LICENSE for details.