Coder Social home page Coder Social logo

andreaselia / laravel-api-to-postman Goto Github PK

View Code? Open in Web Editor NEW
902.0 21.0 94.0 294 KB

Generate a Postman collection automatically from your Laravel API

License: MIT License

PHP 99.93% JavaScript 0.07%
postman collection api route generator laravel-package insomnia

laravel-api-to-postman's Introduction

Laravel API to Postman Header

Latest Stable Version StyleCI

Laravel API to Postman

This package allows you to automatically generate a Postman collection based on your API routes. It also provides basic configuration and support for bearer auth tokens and basic auth for routes behind an auth middleware.

For POST and PUT requests that utilizes a FormRequest, you can optionally scaffold the request, and publish rules in raw or human readable format.

Postman Schema

The generator works for the latest version of the Postman Schema at the time of publication (v2.1.0).

Installation

Install the package:

composer require andreaselia/laravel-api-to-postman

Publish the config file:

php artisan vendor:publish --provider="AndreasElia\PostmanGenerator\PostmanGeneratorServiceProvider" --tag="postman-config"

Configuration

You can modify any of the api-postman.php config values to suit your export requirements.

Click here to view the config attributes.

Usage

The output of the command being ran is your storage/app directory.

To use the command simply run:

php artisan export:postman

The following usage will generate routes with the bearer token specified.

php artisan export:postman --bearer="1|XXNKXXqJjfzG8XXSvXX1Q4pxxnkXmp8tT8TXXKXX"

The following usage will generate routes with the basic auth specified.

php artisan export:postman --basic="username:password123"

If both auths are specified, bearer will be favored.

Examples

This is with the default configuration and a bearer token passed in:

php artisan export:postman --bearer=123456789

Contributing

You're more than welcome to submit a pull request, or if you're not feeling up to it - create an issue so someone else can pick it up.

laravel-api-to-postman's People

Contributors

abdullahobaid avatar ajanes93 avatar almightynassar avatar andreaselia avatar jmgoncalves97 avatar johnnybenson avatar martincic avatar menkveld-24 avatar oooiik avatar robertmarney avatar tomirons avatar tryv avatar tuandp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-api-to-postman's Issues

formdata information not generated

Hey,
I created on route for registration and I'm to add form data dummy information but when generating the Json file they don't appear.
is there another way to add the form data?

route.php:
Route::post('/register', [UserController::class, 'register']);

api-postman.php:
**formdata part

    |--------------------------------------------------------------------------
    | Enable Form Data
    |--------------------------------------------------------------------------
    |
    | Determines whether or not form data should be handled.
    |
    */
    'enable_formdata' => true,
    /*
    |--------------------------------------------------------------------------
    | Form Data
    |--------------------------------------------------------------------------
    |
    | The key/values to requests for form data dummy information.
    |
    */

    'formdata' => [
         'first_name' => 'test1',
         'last_name' => 'test1',
         'email' => '[email protected]',
         'password' => '123456',
         'password_confirmation' => '123456',
         'terms_and_conditions' => true
    ],

and the generated Json file:
{"variable":[{"key":"base_url","value":"http:\/\/localhost"}],"info":{"name":"2021_11_16_120858_laravel_collection.json","schema":"https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json"},"item":[{"name":"api\/register","request":{"method":"POST","header":[{"key":"Accept","value":"application\/json"},{"key":"Content-Type","value":"application\/json"}],"url":{"raw":"{{base_url}}\/api\/register","host":"{{base_url}}\/api\/register"}}}]}

Trying to access array offset on value of type null

I got this Error when running
at C:\xampp\htdocs\Category\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:275
271| {
272| $this->filename = str_replace(
273| ['{timestamp}', '{app}'],
274| [date('Y_m_d_His'), Str::snake(config('app.name'))],

275| $this->config['filename']
276| );
277| }
278|
279| protected function setBearerToken()

1 C:\xampp\htdocs\Category\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:275
Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Trying to access array offset on value of type null", "C:\xampp\htdocs\Category\vendor\andreaselia\laravel-api-to
-postman\src\Commands\ExportPostmanCommand.php", [])

2 C:\xampp\htdocs\Category\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:48
AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::setFilename()

Empty Postman json file

Hello.

The output for this api.php file is empty:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\TeamController;
use App\Http\Controllers\ThemeController;
use App\Http\Controllers\PluginController;
use App\Http\Controllers\CompanyController;
use App\Http\Controllers\ProjectController;
use App\Models\ProjectCollaborationRequestTeam;
use App\Models\ProjectCollaborationRequestUser;
use App\Http\Controllers\ProjectBillingController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\FeedbackController;
use App\Http\Controllers\AdminLoginController;
use App\Models\ProjectCollaborationRequestCompany;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your applica    tion. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('guest:api')->group(function() {
    Route::post('/login', [AuthController::class, 'login']);
    Route::get('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/authOtp', [AuthController::class, 'authOtp']);
    Route::post('/checkuser', [AuthController::class, 'checkUser']);
    Route::post('updatePassword', [AuthController::class, 'updatePassword']); // login user session details
    Route::post('deleteUser', [AuthController::class, 'deleteUser']); // delete user
    

    //admin login
    Route::post('/admin/login', [AdminLoginController::class, 'login']);
   
});


Route::middleware([
    'auth:api',
    'bindings',
])->group(function() {
    // all routes will be POST, PUT, PATCH, DELETE
    //for get auth user details
    Route::get('/getUserDetails', function () {
        return auth()->user();
    });
    Route::post('/updateUserDetails',[AuthController::class, 'updateUserDetails']);
    Route::post('/addConnecterJson', [ProjectController::class, 'addConnecterJson']);
    Route::patch('updatePackageList/{plugin?}/{version?}', [PluginController::class, 'updatePackageList']);
    Route::delete('deletePackageList/{plugin}',[PluginController::class,'deletePackageList']);
    
    // company routes
    Route::put('/company', [CompanyController::class, 'put']); // add
    Route::patch('/company/{company}', [CompanyController::class, 'patch']); // update
    Route::delete('/company/{company}', [CompanyController::class, 'delete']); // delete

    // company user routes
    Route::put('/company/{company}/user/{user}', [CompanyController::class, 'putUser']); // add company user
    Route::patch('/company/{company}/user/{user}', [CompanyController::class, 'patchUser']); // update company user (for permissions)
    Route::delete('/company/{company}/user/{user}', [CompanyController::class, 'deleteUser']); // delete company user

    // team routes
    Route::post('/company/{company}/teams', [TeamController::class, 'index']); // show all company teams
    Route::post('/teams', [TeamController::class, 'index']); // show all teams (of the user)

    Route::put('/company/{company}/team', [TeamController::class, 'put']); // add team
    Route::patch('/team/{team}', [TeamController::class, 'patch']); // update team
    Route::delete('/team/{team}', [TeamController::class, 'delete']); // delete team

    // team user routes
    Route::put('/team/{team}/user/{user}', [TeamController::class, 'putUser']); // add team user
    Route::patch('/team/{team}/user/{user}', [TeamController::class, 'patchUser']); // update team user (for permissions)
    Route::delete('/team/{team}/user/{user}', [TeamController::class, 'deleteUser']); // delete team user

    // project routes
    Route::post('/project/{project}', [ProjectController::class, 'index']); // show project
    Route::post('/projects', [ProjectController::class, 'indexAll']); // show all projects (of the user)

    Route::put('/team/{team}/project', [ProjectController::class, 'put']); // add project
    Route::patch('/project/{project}', [ProjectController::class, 'patch']); // update project
    Route::delete('/project/{project}', [ProjectController::class, 'delete']); // delete project

    Route::put('/project/{project}/user/{user}', [ProjectCollaborationRequestUser::class, 'put']); // send collaboration request to user
    Route::patch('/project/{project}/user/{user}', [ProjectCollaborationRequestUser::class, 'patch']); // modify the collaboration request sent to the user

    Route::put('/project/{project}/team/{team}', [ProjectCollaborationRequestTeam::class, 'put']); // send collaboration request to team
    Route::patch('/project/{project}/team/{team}', [ProjectCollaborationRequestTeam::class, 'patch']); // modify the collaboration request sent to the team 

    Route::put('/project/{project}/company/{company}', [ProjectCollaborationRequestCompany::class, 'put']); // send collaboration request to company
    Route::patch('/project/{project}/company/{company}',  [ProjectCollaborationRequestCompany::class, 'patch']); // modify the collaboration request sent to the company

    // project plugin routes
    Route::patch('/project/{project}/plugins', [ProjectController::class, 'syncPlugins']); // sync project plugins with this list
    Route::post('projects/user', [ProjectController::class, 'syncUserplugins']); // sync project user with this list
    Route::post('projects/environment', [ProjectController::class, 'updateComposerJson']); // add and update the composer json in the database.

    Route::post('composer/addqueue', [PluginController::class, 'addQueue']); // add composer queue in the project

    Route::post('plugins/user', [PluginController::class, 'getUserPlugins']); // this plugin list for the list users
    Route::post('plugins/addremove', [PluginController::class, 'addRemoveUserPlugins']); // add remove plugin list for the list users
    Route::post('plugins/session', [PluginController::class, 'userSession']); // login user session details
    Route::post('plugins/sessionStore', [PluginController::class, 'userSessionStore']); // login user session details
    
        Route::patch('/project/{project}/plugin/{plugin}')->scopeBindings(); // update project plugin

    //project billing routes
    Route::post('/project/{project}/billing', [ProjectBillingController::class, 'index']);

    // user routes
    Route::post('/user/{user}/projects', [UserController::class, 'projects']); // show all the projects this user has access to
    Route::post('/user/{user}',[UserController::class,'index']);

    Route::post('/projectPlugins', [PluginController::class, 'projectPlugins']);

    Route::post('/feebackform', [FeedbackController::class, 'feebackform']);  

    //get Plugin data by type
    Route::post('/getPluginData', [PluginController::class, 'getPluginData']);

    Route::post('/getEnvByProject', [ProjectController::class, 'getEnvByProject']);

    // get package List
    Route::post('/packageList', [PluginController::class, 'packageList']); 

});

Route::post('/plugins', [PluginController::class, 'index']);
Route::post('/allplugins', [PluginController::class, 'allPlugins']);
Route::post('/allVersion', [PluginController::class, 'allVersions']);




Route::post('/themes', [ThemeController::class, 'index']);

Laravel 10

Laravel 10 is out. Could you update the dependancy reqs?

work in laravel < 6 ?

hi

I tried to generate the file of my routes in an older laravel that I have...

Where the routes are in the way
app\Http\routes.php

but the generated file is something like this...

{"variable":[{"key":"base_url","value":"http://localhost:8000"}],"info":{"name":"2022_03_07_074621_test_collection.json","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"item":[]}

Argument count error when enable_formdata is true

  1. Add a route with reflection method
$router->get('showWithReflectionMethod', [ExampleController::class, 'showWithReflectionMethod'])->name('show-with-reflection-method');
  1. Method in controller
    public function showWithReflectionMethod(ExampleService $service): array
    {
        return $service->getRequestData();
    }
  1. ExampleService constructor
    public function __construct(Request $request)
    {
        $this->request = $request;
    }
  1. Set api-postman.enable_formdata => true

Error

ArgumentCountError: Too few arguments to function AndreasElia\PostmanGenerator\Tests\Fixtures\ExampleService::__construct()

form update request unique

failed to export postman when form request has params. in my case form update request unique, email, {USER_ID}

Call to undefined method Illuminate\Routing\RouteAction::containsSerializedClosure()

  Error

  Call to undefined method Illuminate\Routing\RouteAction::containsSerializedClosure()

  at C:\inetpub\wwwroot\xxxxxxx\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:145
    141|
    142|     protected function getReflectionMethod(array $routeAction): ?object
    143|     {
    144|         // Hydrates the closure if it is an instance of Opis\Closure\SerializableClosure
  > 145|         if (RouteAction::containsSerializedClosure($routeAction)) {
    146|             $routeAction['uses'] = unserialize($routeAction['uses'])->getClosure();
    147|         }
    148|
    149|         if ($routeAction['uses'] instanceof Closure) {

  1   C:\inetpub\wwwroot\xxxxxxx\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:74
      AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::getReflectionMethod([Object(Closure), "App\Http\Controllers", "api"])

  2   C:\inetpub\wwwroot\xxxxxxx\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:36
      AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::handle()

Structured export has duplicated entries

It seems that when using structured export some of the endpoints are duplicated in a way that it creates them as a folder and as a single route in the root folder. Also post methods are not structured in their own folders. I'll try to explain it via example:

// WEBHOOK ROUTES
Route::prefix('webhooks')->name('webhooks.')->group(function ($route) {
	$c = WebhookController::class;

	// GET
	$route->get('', [$c, 'index'])->name('list');
	$route->get('{id}', [$c, 'single'])->name('single');

	// POST
	$route->post('', [$c, 'store'])->name('store');
	$route->post('{id}', [$c, 'update'])->name('update');

	// DELETE
	$route->delete('', [$c, 'deleteAll'])->name('delete-all');
	$route->delete('{id}', [$c, 'delete'])->name('remove');
});

And this is the output:
IMAGE

Trying to access array offset on value of type null

php artisan export:postman

ErrorException : Trying to access array offset on value of type null

at D:....\API\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:416
412| {
413| $this->filename = str_replace(
414| ['{timestamp}', '{app}'],
415| [date('Y_m_d_His'), Str::snake(config('app.name'))],

416| $this->config['filename']
417| );
418| }
419|
420| protected function setAuthToken()

Exception trace:

1 Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Trying to access array offset on value of type null", "D:...\API\vendor\andreaselia\laravel-api-to-postman
src\Commands\ExportPostmanCommand.php", [])
D:...\API\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:416

2 AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::setFilename()
D:....\API\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:65

Not support custom rules?

Environment:

Laravel 9.14.1
PHP 8.1.6
laravel-api-to-postman 1.12.0

When executing php artisan export:postman with enable_formdata = true it throws an error:
圖片

It works well when enable_formdata = false.

Here is my request and rule:

class PasswordUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'current_password' => [
                'required',
                'string',
                new CurrentPasswordRule(),
            ],
            'password'         => [
                'required',
                'confirmed',
                'min:8',
                new WeakPasswordRule(),
            ],
        ];
    }
}
class CurrentPasswordRule implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return Hash::check($value, auth()->user()->password);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return __('Your current password is not valid');
    }
}

Does this package not yet support custom rules? Or am I doing something wrong?

Unable to install / update

Hi,

I have just run a composer update in my project, there appears to be a problem now with the filename section -

Undefined index: filename

  at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:240
    236▕     {
    237▕         return str_replace(
    238▕             ['{timestamp}', '{app}'],
    239▕             [date('Y_m_d_His'), Str::snake(config('app.name'))],
  ➜ 240▕             $this->config['filename']
    241▕         );
    242▕     }
    243▕
    244▕     protected function isStructured()

      +2 vendor frames
  3   [internal]:0
      AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::__construct()

      +12 vendor frames
  16  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

Composer File -

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.3|^8.0",
        "andreaselia/laravel-api-to-postman": "^1.2",
        "fideloper/proxy": "^4.4",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/fortify": "^1.7",
        "laravel/framework": "^8.12",
        "laravel/passport": "^10.1",
        "laravel/tinker": "^2.5",
        "livewire/livewire": "^2.3",
        "lnchuk/laravel-extended-resource": "dev-master",
        "maatwebsite/excel": "^3.1",
        "matthewbdaly/laravel-azure-storage": "^1.6",
        "mediconesystems/livewire-datatables": "dev-master",
        "predis/predis": "^1.1",
        "silber/bouncer": "v1.0.0-rc.10"
    },
    "require-dev": {
        "barryvdh/laravel-debugbar": "^3.5",
        "barryvdh/laravel-ide-helper": "^2.9",
        "facade/ignition": "^2.5",
        "fakerphp/faker": "^1.9.1",
        "laravel/dusk": "^6.11",
        "laravel/homestead": "^11.4",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.2",
        "nunomaduro/collision": "^5.0",
        "phpunit/phpunit": "^9.3.3"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

Install problem

I have problem while install the package by composer:

  Problem 1
    - andreaselia/laravel-api-to-postman[v1.6.0, ..., v1.6.1] require illuminate/config ^8.0 -> found illuminate/config[v8.0.0, ..., 8.x-dev] but it conflicts with another require.
    - Root composer.json requires andreaselia/laravel-api-to-postman ^1.6 -> satisfiable by andreaselia/laravel-api-to-postman[v1.6.0, v1.6.1].

Composer file:

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.4.0",
        "ext-mbstring": "*",
        "doctrine/dbal": "^2.9",
        "ejarnutowski/laravel-api-key": "^1.0",
        "facade/ignition": "^2.3",
        "fideloper/proxy": "^4.0",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "6.5.5",
        "laravel/cashier": "^12.5",
        "laravel/framework": "^7.0",
        "laravel/passport": "9.x",
        "laravel/tinker": "^2.0",
        "league/flysystem-aws-s3-v3": "^1.0",
        "predis/predis": "^1.1",
        "sentry/sentry-laravel": "^2.2",
        "stripe/stripe-php": "^7.61",
        "tymon/jwt-auth": "^1.0"
    },
    "require-dev": {
        "beyondcode/laravel-dump-server": "^1.0",
        "filp/whoops": "^2.0",
        "fzaninotto/faker": "^1.4",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^4.1",
        "phpunit/phpunit": "^8.5",
        "apoplavs/laravel-autodoc": "^1.0",
        "ronasit/laravel-entity-generator": "^1.3"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/",
            "Apoplavs\\Support\\AutoDoc\\": "src/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi",
            "@php artisan vendor:publish --provider=\"Apoplavs\\Support\\AutoDoc\\AutoDocServiceProvider\""
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
            "@php artisan storage:link"
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

Can anyone help me to solve this problem?

Class "" does not exist

`
at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:159
155▕ return new ReflectionFunction($routeAction['uses']);
156▕ }
157▕
158▕ $routeData = explode('@', $routeAction['uses']);
➜ 159▕ $reflection = new ReflectionClass($routeData[0]);
160▕
161▕ if (! $reflection->hasMethod($routeData[1])) {
162▕ return null;
163▕ }

  +15 vendor frames 

16 artisan:35
Illuminate\Foundation\Console\Kernel::handle()
`

Trying to access array offset on value of type null $this->config['filename']

Getting the following error, with laravel 7 and php 7.4:

> php artisan vendor:publish --provider="AndreasElia\PostmanGenerator\PostmanGeneratorServiceProvider" --tag="postman-config"
PHP Warning:  Module 'redis' already loaded in Unknown on line 0
Copied File [/vendor/andreaselia/laravel-api-to-postman/config/api-postman.php] To [/config/api-postman.php]
Publishing complete
> php artisan export:postman
Trying to access array offset on value of type null

  at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:264
    260|     {
    261|         $this->filename = str_replace(
    262|             ['{timestamp}', '{app}'],
    263|             [date('Y_m_d_His'), Str::snake(config('app.name'))],
  > 264|             $this->config['filename']
    265|         );
    266|     }
    267| 
    268|     protected function setBearerToken()

More documentation

Please can you provide more documentation, samples output results and exported data structure ?

Exception with Opis\Closure\SerializableClosure (have solution)

I already have a solution, just wanted to write up the issue first to explain and allow for any discussion with the approach.

I installed this package using composer require --dev andreaselia/laravel-api-to-postman, which added "andreaselia/laravel-api-to-postman": "^1.7", to my composer.json. I then published the config file and edited it for my project.

I have a route that uses Laravel's API Resources. An example:

<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\User\UserResource;

Route::group(['prefix' => 'profile', 'as' => 'profile.'], function () {
    Route::get('/', function () {
        return new UserResource(Auth::user());
    })->name('index');
});

Running php artisan export:postman results in the following:

$ php artisan export:postman

   ReflectionException 

  Class C:32:"Opis\Closure\SerializableClosure":289:{ does not exist

  at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:153
    149▕             return new ReflectionFunction($routeAction['uses']);
    150▕         }
    151▕ 
    152▕         $routeData = explode('@', $routeAction['uses']);
  ➜ 153▕         $reflection = new ReflectionClass($routeData[0]);
    154▕ 
    155▕         if (! $reflection->hasMethod($routeData[1])) {
    156▕             return null;
    157▕         }

      +15 vendor frames 
  16  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Debugging the issue shows that there are no problems with traditional Controllers, only the profile routes which use API Resources (testing the feature out). Looked into both vendor\laravel\framework\src\Illuminate\Routing\Route.php and vendor\laravel\framework\src\Illuminate\Routing\RouteAction.php and saw multiple references to serialization. Not sure what exactly leads to my profile routes being serialized. However, the inspiration is in lines 225-227 in Route.php:

if ($this->isSerializedClosure()) {
    $callable = unserialize($this->action['uses'])->getClosure();
}

Using this, I added to the getReflectionMethod() function of src\Commands\ExportPostmanCommand.php on line 143:

// Hydrates the closure if it is an instance of Opis\Closure\SerializableClosure
if (is_string($routeAction['uses']) && Str::startsWith($routeAction['uses'], 'C:32:"Opis\\Closure\\SerializableClosure') !== false) {
    $routeAction['uses'] = unserialize($routeAction['uses'])->getClosure();
}

I edit $routeAction['uses'] in place because it changes the code the least, leverages existing Closure code.

I'll submit the change when I get the chance, unless there is a simpler option to turn off route serialization that I simply missed.

Running import in my project I got error ...

After installing AndreasElia/laravel-api-to-postman I tried to import my project, but got error :

master@master-laptop:/mnt/_work_sdb8/wwwroot/lar/PublishBuyDocs$ php artisan export:postman

   ReflectionException 

  Class "O:47:"Laravel\SerializableClosure\SerializableClosure":1:{s:12:"serializable";O:46:"Laravel\SerializableClosure\Serializers\Signed":2:{s:12:"serializable";s:303:"O:46:"Laravel\SerializableClosure\Serializers\Native":5:{s:3:"use";a:0:{}s:8:"function";s:85:"function (\Illuminate\Http\Request $request) {
        return $request->user();
    }";s:5:"scope";s:37:"Illuminate\Routing\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000004370000000000000000";}";s:4:"hash";s:44:"Np6TXB8CPOs/P0pRtmBIG8RKahtC8oq1L+OoYoVPPmE=";}}" does not exist

  at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:195
    191▕             return new ReflectionFunction($routeAction['uses']);
    192▕         }
    193▕ 
    194▕         $routeData = explode('@', $routeAction['uses']);
  ➜ 195▕         $reflection = new ReflectionClass($routeData[0]);
    196▕ 
    197▕         if (! $reflection->hasMethod($routeData[1])) {
    198▕             return null;
    199▕         }

      +15 vendor frames 
  16  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()
master@master-laptop:/mnt/_work_sdb8/wwwroot/lar/PublishBuyDocs$ php -v
PHP 8.1.2 (cli) (built: Jan 24 2022 10:42:33) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies
master@master-laptop:/mnt/_work_sdb8/wwwroot/lar/PublishBuyDocs$ php artisan --version
Laravel Framework 9.4.1

In composer.json :

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "require": {
        "php": "^8.0.2",
        "andreaselia/laravel-api-to-postman": "^1.11",
        "bensampo/laravel-enum": "^5.2",
        "cviebrock/eloquent-sluggable": "^9.0",
        "guzzlehttp/guzzle": "^7.2",
        "laravel/framework": "^9.2",
        "laravel/passport": "^10.3",
        "laravel/sanctum": "^2.14.1",
        "laravel/telescope": "^4.8",
        "laravel/tinker": "^2.7",
        "orangehill/iseed": "^3.0",
        "spatie/laravel-permission": "^5.5"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^1.0"
    },
    "autoload": {
        "files": [
            "app/Library/helper.php"
        ],
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

In my routes/api.php :

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\AuthController;
use App\Http\Controllers\PageController;

use App\Http\Controllers\AuthorsController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/


Route::middleware('auth:api')->prefix('v1')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });


    Route::post('/register', [AuthController::class,'register']);
    Route::post('/login', [AuthController::class,'login']);


    Route::group(['middleware' => 'auth'], function () {

//        Route::get('/profile', 'UserProfileController@index');
//        Route::put('/profile/{user_id}', 'UserProfileController@update');

        Route::post('/logout', [AuthController::class, 'logout'] );

        Route::resource('/authors', AuthorsController::class);

        // PAGES BLOCK BEGIN
        Route::resource('/pages', PageController::class);
        Route::group(['prefix' => 'pages'], function () {
            Route::put('{id}/publish', [PageController::class, 'publish']);
            Route::put('{id}/unpublish', [PageController::class, 'unpublish']);
//        Route::put('{id}/unpublish', 'PageController@unpublish');
        });
        // PAGES BLOCK END


    });

});

and in routes/web.php :

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

I have Postman v9.0.8.

What could raise this error and how can it be fixed?

Thanks!

GET request with formData for query parameters

Hi,

I have a problem with generating correct documentation whenever I have a GET request that has form data for "query" parameters. It resolves URL for Postman as:
?lat&lng&distance&start_date&end_date&filters
instead of:
{{base_url}}/api/v1/garages/find?lat&lng&distance&start_date&end_date&filters
while on the name there is the correct route path...
image

Version of package: v2.0.2
Version of Laravel: v10.48.3

Here is my function:

/**
     * Find available garages
     */
    public function index(FindRequest $request)
    {
        $garageAvailableFor = 'visitor';

        $user = $this->guard()->user();

        if ($user && $user->employee_id)
            $garageAvailableFor = 'employee';

        $departmentId = NULL;
        $workLocationId = NULL;
        $customerDailyInventoryExemption = false;

        if ($user) {
            $departmentId = $this->guard()->user()->entity_work_location_department_id;
            $workLocationId = $this->guard()->user()->entity_work_location_id;
            $customerDailyInventoryExemption = !!$user->daily_inventory_exemption;
        }

        return response()->json(
            $this->garages->getFilteredDaily(
                !is_null($request->get('lat')) ? $request->get('lat') : NULL,
                !is_null($request->get('lng')) ? $request->get('lng') : NULL,
                !is_null($request->get('distance')) ? $request->get('distance') : NULL,
                $request->get('start_date') ?: NULL,
                $request->get('end_date') ?: NULL,
                $request->get('filters') ?: [],
                $garageAvailableFor,
                $workLocationId,
                $departmentId,
                $customerDailyInventoryExemption
            )
        );
    }

And here is a FindRequest:

<?php

namespace App\Http\Requests\Api\Garage;

use App\Http\Requests\FormRequest;

class FindRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'lat'        => 'required_with:lng,distance',
            'lng'        => 'required_with:lat,distance',
            'distance'   => 'required_with:lat,lng',
            'start_date' => 'required_with:end_date|date',
            'end_date'   => 'required_with:start_date|date',
            'filters'    => 'sometimes|array',
        ];
    }
}

Opposite of that everything looks nice :) The only question I have is whether there is an option to add Authorization headers per middleware group? I have different key name and value for /api and for /webhooks

Laravel 9 Support

Hi,

Laravel 9 will be out in a few days so can you add |^9 to composer.json constraints?

Thx!

ReflectionException

Hi,

on a project from scratch with Laravel 9.19

I have this error :


   ReflectionException

  Class "O:47:"Laravel\SerializableClosure\SerializableClosure":1:{s:12:"serializable";O:46:"Laravel\SerializableClosure\Serializers\Signed":2:{s:12:"serializable";s:295:"O:46:"Laravel\SerializableClosure\Serializers\Native":5:{s:3:"use";a:0:{}s:8:"function";s:77:"function (\Illuminate\Http\Request $request) {
    return $request->user();
}";s:5:"scope";s:37:"Illuminate\Routing\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000004400000000000000000";}";s:4:"hash";s:44:"/BJGjgLOCrK/HYxZhXaHlU4J/cO5KqbSFiXWK3axFYA=";}}" does not exist

  at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:205
    201▕             return new ReflectionFunction($routeAction['uses']);
    202▕         }
    203▕
    204▕         $routeData = explode('@', $routeAction['uses']);
  ➜ 205▕         $reflection = new ReflectionClass($routeData[0]);
    206▕
    207▕         if (! $reflection->hasMethod($routeData[1])) {
    208▕             return null;
    209▕         }

      +15 vendor frames
  16  artisan:37

composer.json

    "require": {
        "php": "^8.0.2",
        "andreaselia/laravel-api-to-postman": "^1.12",
        "google/apiclient": "^2.12.1",
        "guzzlehttp/guzzle": "^7.2",
        "laravel/framework": "^9.19",
        "laravel/sanctum": "^2.14.1",
        "laravel/tinker": "^2.7"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.15",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^1.0"
    },

and api.php (route)


Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Export command says that postman collection was exported but no JSON file created

Hey guys,
I am using Laravel 8, PHP 8. I am trying to generate a postman collection out of my API.

I installed this package and used the php artisan export:postman command

www@f86a5c7089bb:/var/www$ php artisan export:postman --bearer="4|hidden"
Postman Collection Exported: postman/2022_02_19_173418_on_account_collection.json

also tried

www@f86a5c7089bb:/var/www$ php artisan export:postman
Postman Collection Exported: postman/2022_02_19_172712_on_account_collection.json

It says it generated a json file but it's not generated. (Nowhere to be found)

I am trying to generate this from docker in my local envirement

my config files looks like this:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Base URL
    |--------------------------------------------------------------------------
    |
    | The base URL for all of your endpoints.
    |
    */

    'base_url' => env('APP_URL', 'http://localhost:1111'),

    /*
    |--------------------------------------------------------------------------
    | Collection Filename
    |--------------------------------------------------------------------------
    |
    | The name for the collection file to be saved.
    |
    */

    'filename' => '{timestamp}_{app}_collection.json',

    /*
    |--------------------------------------------------------------------------
    | Structured
    |--------------------------------------------------------------------------
    |
    | If you want folders to be generated based on namespace.
    |
    */

    'structured' => false,

    /*
    |--------------------------------------------------------------------------
    | Auth Middleware
    |--------------------------------------------------------------------------
    |
    | The middleware which wraps your authenticated API routes.
    |
    | E.g. auth:api, auth:sanctum
    |
    */

    'auth_middleware' => 'auth:api',

    /*
    |--------------------------------------------------------------------------
    | Headers
    |--------------------------------------------------------------------------
    |
    | The headers applied to all routes within the collection.
    |
    */

    'headers' => [
        [
            'key' => 'Accept',
            'value' => 'application/json',
        ],
        [
            'key' => 'Content-Type',
            'value' => 'application/json',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Enable Form Data
    |--------------------------------------------------------------------------
    |
    | Determines whether or not form data should be handled.
    |
    */

    'enable_formdata' => true,

    /*
    |--------------------------------------------------------------------------
    | Form Data
    |--------------------------------------------------------------------------
    |
    | The key/values to requests for form data dummy information.
    |
    */

    'formdata' => [
        // 'email' => '[email protected]',
        // 'password' => 'changeme',
    ],

    /*
    |--------------------------------------------------------------------------
    | Include Middleware
    |--------------------------------------------------------------------------
    |
    | The routes of the included middleware are included in the export.
    |
    */

    'include_middleware' => ['api'],

    /*
    |--------------------------------------------------------------------------
    | Disk Driver
    |--------------------------------------------------------------------------
    |
    | Specify the configured disk for storing the postman collection file.
    |
    */

    'disk' => 'local',

];

Generator fails when using Rule Objects - Check if rule is array before looking for needle

  TypeError 

  in_array(): Argument #2 ($haystack) must be of type array, Illuminate\Validation\Rules\Unique given

  at C:\sites\procure\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:100
     96|                             if (is_string($rule)) {
     97|                                 $rule = preg_split('/\s*\|\s*/', $rule);
     98|                             }
     99| 
  > 100|                             if (in_array('confirmed', $rule)) {
    101|                                 $requestRules[] = $fieldName.'_confirmation';
    102|                             }
    103|                         }
    104|                     }

Not perfect but a quick fix is to ignore these rules:

if (is_array($rule) && in_array('confirmed', $rule)) {
    $requestRules[] = $fieldName.'_confirmation';
}

Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException

i just did the same thing as you escribe in the readme but i cant get the data instead i got this error Symfony\Component\HttpKernel\Exception\NotFoundHttpException in response.
here are my api resoure :
Route::apiResource('racks', App\Http\Controllers\API\RackController::class);
Route::apiResource('books', App\Http\Controllers\API\BookController::class);
in case of full api review here is github code
postman api: apis

class "int" not found

I have only one route in my api.php route file

Route::get("/v1/test/{id}",[\App\Http\Controllers\ApiController::class,'index']);

And my ApiController is like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ApiController extends Controller
{
    //

    public function index(int $id)
    {
        echo "test";
    }
}

I have changed both structured and enable_formdata to true . when I run the command I get this error in the terminal.

Error

Class "int" not found

at vendor/andreaselia/laravel-api-to-postman/src/Commands/ExportPostmanCommand.php:78
74▕ }
75▕ $firstParameter = $reflectionMethod->getParameters()[0] ?? false;
76▕ if ($firstParameter) {
77▕ $requestClass = $firstParameter->getType()->getName();
➜ 78▕ $requestClass = new $requestClass();
79▕ if ($requestClass instanceof FormRequest) {
80▕ $requestRules = $requestClass->rules();
81▕ $requestRules = array_keys($requestRules);
82▕ }

  +13 vendor frames 

14 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Idea: Lumen Support

Hi, please add lumen compatibility to this helpful project, either to code or in case it is, add to README

Add over-write support

First of all, this is a pretty solid package - it does what it says it does, and efficiently so.

However, there is a lot of features that could be added to make DX even better - and I clearly see and understand how challenging this would be.

I use Postman and Laravel as the only 2 tools when it comes to API development (except may be my IDE). One of the challenge with this package is that this is a "one-time" use package, or for a "uni-directional" approach.

Following works:

  1. Create APIs
  2. Export as Postman collection

Following does not:

  1. Create APIs
  2. Export collection
  3. Change something in Postman - a parameter, or the value of that, comment against a variable, pre-request or test scripts, set/manage Bearer token (or anything else that is within the scope/context of Postman only)
  4. Create more APIs
  5. Export collection again
  6. Over-writes the collection that was changed in Postman

The issue (or rather a feature-request) would be to "update" an API (in the collection) if it already exists - and yes, the prerequisite for this would be that the user has exported the collection from Postman (after changes) and is at the same location where the package is going to export the collection.

I understand this would be more than a "simple" change, and I will try to do a POC of this - not sure "when", could be very long in the future - so if someone else looks at this and wants to add support of not just over-writing the exported collection, but also to keep the changes done by Postman itself, then it would be a pretty awesome feature.

Thanks

Not correctly prefixing urls

Scherm­afbeelding 2024-04-01 om 20 29 51
Route::prefix('v1')->name('v1.')->group(function () {
    Route::get('/user', [UserController::class, 'index'])->name('index');
}

My url should be {{baseUrl}}/v1/user although the '/v1' part is missing in the generated postman json

I have my routes setup like this and it seems to have broken in version 2.x.x of this application.
It only misses the v1 on most of my routes, other nested route groupings work fine though. Seems like it only occurs on the first grouping

creating a new feature to make package generate other routes without having 'api' middleware

Hi @andreaselia
I am considering if we can add a new feature to make it possible to generate routes without having 'api' middleware only.
I saw in ExportPostmanCommand file that the package has this line of code :

 if (empty($middleware) || ! in_array('api', $middleware)) {
                    continue;
 }

I think hard coding the 'api' and just generating postman collection only for routes that have 'api' middleware is not a good way. In my project I have about 200 routes but the package can only generate roughly 20 routes in the exported collection.
I noticed that that's because other routes didn't have 'api' middleware.

argument must be of type array|object, null given

  at C:\inetpub\wwwroot\site\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:93
     89▕                         $rulesParameter = $rulesParameter->getType()->getName();
     90▕                         $rulesParameter = new $rulesParameter;
     91▕                         $rules = method_exists($rulesParameter, 'rules') ? $rulesParameter->rules() : [];
     92▕
  ➜  93▕                         foreach ($rules as $fieldName => $rule) {
     94▕                             $requestRules[] = $fieldName;
     95▕
     96▕                             if (is_string($rule)) {
     97▕                                 $rule = preg_split('/\s*\|\s*/', $rule);

  1   C:\inetpub\wwwroot\site\vendor\andreaselia\laravel-api-to-postman\src\Commands\ExportPostmanCommand.php:93
      Illuminate\Foundation\Bootstrap\HandleExceptions::handleError()

  2   C:\inetpub\wwwroot\site\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:36
      AndreasElia\PostmanGenerator\Commands\ExportPostmanCommand::handle()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.