juststeveking / laravel-transporter
Transporter is a futuristic way to send API requests in PHP. This is an OOP approach to handle API requests.
Installs: 134 781
Dependents: 2
Suggesters: 0
Security: 0
Stars: 465
Watchers: 8
Forks: 26
Open Issues: 2
Requires
- php: ^8.1
- illuminate/contracts: ^10.0|^11.0
- juststeveking/http-status-code: ^2.0
- juststeveking/uri-builder: ^2.0|^3.0
- spatie/laravel-package-tools: ^1.14.1
Requires (Dev)
- brianium/paratest: ^6.9|^7.4
- guzzlehttp/guzzle: ^7.5
- nunomaduro/collision: ^6.4|^8.0
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^1.22.4|^2.34
- phpstan/phpstan: ^1.9.17
- phpunit/phpunit: ^9.6.3|^10.5
- spatie/laravel-ray: ^1.32.2
README
Transporter is a futuristic way to send API requests in PHP. This is an OOP approach to handle API requests.
Installation
You can install the package via composer:
composer require juststeveking/laravel-transporter
You can publish the config file with:
php artisan vendor:publish --provider="JustSteveKing\Transporter\TransporterServiceProvider" --tag="transporter-config"
The contents of the published config file:
return [ 'base_uri' => env('TRANSPORTER_BASE_URI'), ];
Generating Request
To generate an API request to use with Transporter, you can use the Artisan make command:
php artisan make:api-request NameOfYourRequest
This will by default publish as: app/Transporter/Requests/NameOfYourRequest.php
Usage
Transporter Requests are an extention of Laravels PendingRequest
so all of the methods available on a Pending Request is available to you on your requests.
Also when you send the request, you will receive a Illuminate\Http\Client\Response
back, allowing you to do things such as collect($key)
and json()
and failed()
very easily. We are simply just shifting how we send it into a class based approach.
TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]) ->send() ->json();
When building your request to send, you can override the following:
- Request Data using
withData(array $data)
- Request Query Params using
withQuery(array $query)
- Request Path using
setPath(string $path)
Checking the payload
I had a request in an issue to be able to see the request data for a request, so I have added a helper method called payload
which will return whatever has been stored in the request data
property.
$request = TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]); $data = $request->payload(); // ['title' => 'Build a package']
Concurrent Requests
$responses = \JustSteveKing\Transporter\Facades\Concurrently::build()->setRequests([ TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), ]); $responses[0]->json(); $responses[1]->json(); $responses[2]->json();
Concurrency with a Custom key
$responses = \JustSteveKing\Transporter\Facades\Concurrently::build()->setRequests([ TestRequest::build() ->as( key: 'first' ) ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), TestRequest::build() ->as( key: 'second' ) ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), TestRequest::build() ->as( key: 'third' ) ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]), ]); $responses['first']->json(); $responses['second']->json(); $responses['third']->json();
Optional Alias
Instead of the standard send()
method, it is also possible to use the fun alias energize()
. Please note, no sound effects are included.
TestRequest::build() ->withToken('foobar') ->withData([ 'title' => 'Build a package' ]) ->energize() ->json();
Faking a Request or Concurrent
To fake a request, all you need to do is replace the build method with the fake method, which takes an optional status
parameter, to set the status code being returned with the response:
TestRequest::fake( status: 200, )->withToken('foobar') ->withData([ 'title' => 'Build a package' ])->withFakeData([ 'data' => 'faked' ])->send();
$responses = Concurrently::fake()->setRequests([ TestRequest::fake()->setPath( path: '/todos/1', )->as( key: 'first' ), TestRequest::fake()->setPath( path: '/todos/2', )->as( key: 'second' ), TestRequest::fake()->setPath( path: '/todos/3', )->as( key: 'thirds' ), ])->run();
Which will return a response with the data you pass through to withFakeData
, which internally will merge what is on the class with what you pass it. So you can build up an initial state of faked data per class.
Sending XML
Thanks to a fantastic suggestion by @jessarcher we can use a Trait
to allow for easy use of XML in your requests. Using this as a trait makes a lot of sense as most APIs these days use JSON, so it is purely opt in.
To use this, simply use the trait on your request:
<?php declare(strict_types=1); namespace App\Transporter\Requests; use JustSteveKing\Transporter\Concerns\SendsXml; use JustSteveKing\Transporter\Request; class XmlRequest extends Request { use SendsXml; protected string $method = 'POST'; protected string $path = '/your-endpoint'; }
Then all you need to do is call the methods:
XmlRequest::build()->withXml( xml: '<todo><name>Send an XML Requets</name><completed>false</completed></todo>' )->send();
Testing
To run the tests in parallel:
composer run test
To run the tests with a coverage report:
composer run test-coverage
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.