Laravel Pipelines: Build An API
Laravel pipelines are a powerful feature that allows you to build complex workflows by breaking down operations into smaller, reusable stages. Pipelines offer a more efficient, readable, and scalable approach to handling data transformations in your Laravel applications. In this post, we'll explore the basics of pipelines, their benefits, and how to use them to build APIs.
Pipeline Basics
Laravel pipelines are a design pattern that allows you to create a sequence of stages, where each stage receives input data, performs some operation, and then passes the output to the next stage. This pattern is especially useful for processing large data sets, where you need to perform multiple operations on the data before returning the final result. The benefits of using pipelines
By using pipelines, you can:
- Break down complex operations into smaller, reusable stages.
- Simplify your code by separating concerns.
- Improve code readability and maintainability.
- Scale your application more easily.
- Enable parallel processing by running stages concurrently.
- Allow stages to be swapped in and out, depending on your needs.
How to build a simple API in Laravel using pipelines:
First, let's modify our users migration (this file is likely named 2014_10_12_000000_create_users_table.php
in your repository). This modification will introduce the 'dob' field which we will later reference in our API.
1use Illuminate\Database\Migrations\Migration; 2use Illuminate\Database\Schema\Blueprint; 3use Illuminate\Support\Facades\Schema; 4 5return new class extends Migration 6{ 7 /** 8 * Run the migrations. 9 */10 public function up(): void11 {12 Schema::create('users', function (Blueprint $table) {13 $table->id();14 $table->string('name');15 $table->string('email')->unique();16 $table->timestamp('email_verified_at')->nullable();17 $table->string('password');18 $table->string('timezone')->index();19 $table->date('dob')->index();20 $table->rememberToken();21 $table->timestamps();22 });23 }24 25 /**26 * Reverse the migrations.27 */28 public function down(): void29 {30 Schema::dropIfExists('users');31 }32};
Now we need to migrate the table to the database:
1php artisan migrate
From here we will update our UserFactory.php
to include the dob
field which we can generate a fake date for on demand:
database/Factories/UserFactory.php
1namespace Database\Factories;23use Illuminate\Database\Eloquent\Factories\Factory;4use Illuminate\Support\Str;56class UserFactory extends Factory7{8 public function definition(): array9 {10 return [11 'name' => fake()->name(),12 'email' => fake()->unique()->safeEmail(),13 'email_verified_at' => now(),14 'timezone' => fake()->timezone,15 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password16 'dob' => $this->faker->date,17 'remember_token' => Str::random(10),18 ];19 }20}
Now we need to get data into your database. Let's fire up Tinker:
1php artisan tinker
This will now place us in a tinker session. Now type the following into the terminal, then press ENTER
. This will generate 1000 user records into your database:
1\App\Models\User::factory()->times(1000)->create();
Now that we have a decently sized data set, we'll close Tinker and create a controller:
1php artisan make:controller UserSearchController -i
Let's add the route in our api.php
:
routes/web.php
1Route::get('users/search', \App\Http\Controllers\UserSearchController::class);
We'll now take that controller and bootstrap the pipeline:
app/Http/Controllers/UserSearchController.php
1namespace App\Http\Controllers;23use App\Models\User;4use Illuminate\Http\Request;5use Illuminate\Support\Facades\Pipeline;67class UserSearchController extends Controller8{9 /**10 * Handle the incoming request.11 *12 * @param Request $request13 */14 public function __invoke(Request $request)15 {16 $pipelines = [];1718 return Pipeline::send(User::query())19 ->through($pipelines)20 ->thenReturn()21 ->paginate();22 }23}
Right now the code would return the same as if we did this:
1User::paginate()
Before we start adding stages to our pipeline lets visit our endpoint in the browser:
1http://yourdomain.test/api/users/search
1{ 2 "current_page": 1, 3 "data": [ 4 { 5 "id": 1, 6 "name": "Clara Runte", 7 "email": "jmurazik@example.org", 8 "email_verified_at": "2023-03-16T20:50:38.000000Z", 9 "timezone": "America/Sitka", 10 "dob": "1995-12-14", 11 "created_at": "2023-03-16T20:50:39.000000Z", 12 "updated_at": "2023-03-16T20:50:39.000000Z" 13 }, 14 { 15 "id": 2, 16 "name": "Vicky Brown DVM", 17 "email": "kohler.mikel@example.net", 18 "email_verified_at": "2023-03-16T20:50:39.000000Z", 19 "timezone": "Africa/Djibouti", 20 "dob": "1976-06-16", 21 "created_at": "2023-03-16T20:50:39.000000Z", 22 "updated_at": "2023-03-16T20:50:39.000000Z" 23 }, 24 { 25 "id": 3, 26 "name": "Charlotte Gutkowski", 27 "email": "clifford.schumm@example.org", 28 "email_verified_at": "2023-03-16T20:50:39.000000Z", 29 "timezone": "Africa/Gaborone", 30 "dob": "1971-09-23", 31 "created_at": "2023-03-16T20:50:39.000000Z", 32 "updated_at": "2023-03-16T20:50:39.000000Z" 33 }, 34 { 35 "id": 4, 36 "name": "Mariana Hamill", 37 "email": "lbrakus@example.org", 38 "email_verified_at": "2023-03-16T20:50:39.000000Z", 39 "timezone": "Europe/Ljubljana", 40 "dob": "1989-05-13", 41 "created_at": "2023-03-16T20:50:39.000000Z", 42 "updated_at": "2023-03-16T20:50:39.000000Z" 43 }, 44 { 45 "id": 5, 46 "name": "Prof. Ima Zemlak", 47 "email": "heaven.konopelski@example.org", 48 "email_verified_at": "2023-03-16T20:50:39.000000Z", 49 "timezone": "America/Rio_Branco", 50 "dob": "1985-09-04", 51 "created_at": "2023-03-16T20:50:39.000000Z", 52 "updated_at": "2023-03-16T20:50:39.000000Z" 53 }, 54 { 55 "id": 6, 56 "name": "Anissa Wiegand", 57 "email": "turcotte.bernhard@example.com", 58 "email_verified_at": "2023-03-16T20:50:39.000000Z", 59 "timezone": "America/Yakutat", 60 "dob": "1978-10-25", 61 "created_at": "2023-03-16T20:50:39.000000Z", 62 "updated_at": "2023-03-16T20:50:39.000000Z" 63 }, 64 { 65 "id": 7, 66 "name": "Vanessa Metz", 67 "email": "carson09@example.net", 68 "email_verified_at": "2023-03-16T20:50:39.000000Z", 69 "timezone": "Europe/Oslo", 70 "dob": "1987-07-26", 71 "created_at": "2023-03-16T20:50:39.000000Z", 72 "updated_at": "2023-03-16T20:50:39.000000Z" 73 }, 74 { 75 "id": 8, 76 "name": "Dr. Alexandre Kunze Jr.", 77 "email": "caden.beahan@example.net", 78 "email_verified_at": "2023-03-16T20:50:39.000000Z", 79 "timezone": "America/Eirunepe", 80 "dob": "2017-05-19", 81 "created_at": "2023-03-16T20:50:39.000000Z", 82 "updated_at": "2023-03-16T20:50:39.000000Z" 83 }, 84 { 85 "id": 9, 86 "name": "Darrel Barton", 87 "email": "casimer64@example.org", 88 "email_verified_at": "2023-03-16T20:50:39.000000Z", 89 "timezone": "America/Matamoros", 90 "dob": "1973-11-02", 91 "created_at": "2023-03-16T20:50:39.000000Z", 92 "updated_at": "2023-03-16T20:50:39.000000Z" 93 }, 94 { 95 "id": 10, 96 "name": "Prof. Darrick Kozey", 97 "email": "rosalee56@example.org", 98 "email_verified_at": "2023-03-16T20:50:39.000000Z", 99 "timezone": "Africa/Juba",100 "dob": "2020-12-15",101 "created_at": "2023-03-16T20:50:39.000000Z",102 "updated_at": "2023-03-16T20:50:39.000000Z"103 },104 {105 "id": 11,106 "name": "Gage Crooks",107 "email": "devante.erdman@example.net",108 "email_verified_at": "2023-03-16T20:50:39.000000Z",109 "timezone": "America/Costa_Rica",110 "dob": "1985-06-01",111 "created_at": "2023-03-16T20:50:39.000000Z",112 "updated_at": "2023-03-16T20:50:39.000000Z"113 },114 {115 "id": 12,116 "name": "Candelario Kub",117 "email": "austin.hartmann@example.net",118 "email_verified_at": "2023-03-16T20:50:39.000000Z",119 "timezone": "America/Punta_Arenas",120 "dob": "2006-02-10",121 "created_at": "2023-03-16T20:50:39.000000Z",122 "updated_at": "2023-03-16T20:50:39.000000Z"123 },124 {125 "id": 13,126 "name": "Sammy Kirlin",127 "email": "tomasa87@example.com",128 "email_verified_at": "2023-03-16T20:50:39.000000Z",129 "timezone": "Africa/Nouakchott",130 "dob": "1972-02-25",131 "created_at": "2023-03-16T20:50:39.000000Z",132 "updated_at": "2023-03-16T20:50:39.000000Z"133 },134 {135 "id": 14,136 "name": "Lysanne Walter",137 "email": "katheryn.tromp@example.org",138 "email_verified_at": "2023-03-16T20:50:39.000000Z",139 "timezone": "Asia/Urumqi",140 "dob": "2004-06-27",141 "created_at": "2023-03-16T20:50:39.000000Z",142 "updated_at": "2023-03-16T20:50:39.000000Z"143 },144 {145 "id": 15,146 "name": "Kurtis Renner",147 "email": "xweber@example.net",148 "email_verified_at": "2023-03-16T20:50:39.000000Z",149 "timezone": "America/Araguaina",150 "dob": "1998-01-13",151 "created_at": "2023-03-16T20:50:39.000000Z",152 "updated_at": "2023-03-16T20:50:39.000000Z"153 }154 ],155 "first_page_url": "http://yourdomain.test/users/search?page=1",156 "from": 1,157 "last_page": 67,158 "last_page_url": "http://yourdomain.test/users/search?page=67",159 "links": [160 {161 "url": null,162 "label": "« Previous",163 "active": false164 },165 {166 "url": "http://yourdomain.test/users/search?page=1",167 "label": "1",168 "active": true169 },170 {171 "url": "http://yourdomain.test/users/search?page=2",172 "label": "2",173 "active": false174 },175 {176 "url": "http://yourdomain.test/users/search?page=3",177 "label": "3",178 "active": false179 },180 {181 "url": "http://yourdomain.test/users/search?page=4",182 "label": "4",183 "active": false184 },185 {186 "url": "http://yourdomain.test/users/search?page=5",187 "label": "5",188 "active": false189 },190 {191 "url": "http://yourdomain.test/users/search?page=6",192 "label": "6",193 "active": false194 },195 {196 "url": "http://yourdomain.test/users/search?page=7",197 "label": "7",198 "active": false199 },200 {201 "url": "http://yourdomain.test/users/search?page=8",202 "label": "8",203 "active": false204 },205 {206 "url": "http://yourdomain.test/users/search?page=9",207 "label": "9",208 "active": false209 },210 {211 "url": "http://yourdomain.test/users/search?page=10",212 "label": "10",213 "active": false214 },215 {216 "url": null,217 "label": "...",218 "active": false219 },220 {221 "url": "http://yourdomain.test/users/search?page=66",222 "label": "66",223 "active": false224 },225 {226 "url": "http://yourdomain.test/users/search?page=67",227 "label": "67",228 "active": false229 },230 {231 "url": "http://yourdomain.test/users/search?page=2",232 "label": "Next »",233 "active": false234 }235 ],236 "next_page_url": "http://yourdomain.test/users/search?page=2",237 "path": "http://yourdomain.test/users/search",238 "per_page": 15,239 "prev_page_url": null,240 "to": 15,241 "total": 1000242}
Since UserFactory
creates data at random, your data points' will not look exactly like mine.
Now we'll create a class called ByEmail
which will serve as our filter allowing us to "filter by email."
app/Filters/ByEmail.php
1namespace App\Filters;23use Closure;4use Illuminate\Database\Eloquent\Builder;5use Illuminate\Http\Request;67class ByEmail8{9 public function __construct(public Request $request){}1011 public function handle(Builder $query, Closure $next)12 {13 return $next($query)14 ->when($this->request->has('email'),15 fn($query) => $query->where('email', 'regexp', $this->request->email)16 );17 }18}
So what exactly is going on here?
1public function __construct(public Request $request){}
We're asking the service container to return us the current request coming into our application and assign it to a public attribute called $request which we can reference anytime by using $this->request
.
Now lets examine the handle()
method.
1public function handle(Builder $query, Closure $next)2{3 return $next($query)4 ->when($this->request->has('email'),5 fn($query) => $query->where('email', 'regexp', $this->request->email)6 );7}
The first parameter, Builder $query
, serves as the payload being sent into our pipeline, which in our case is the Eloquent Query Builder. The second parameter, Closure $next
, is what is used to send our payload, along with any modifications made to it, onto the next stage in the pipeline.
The when()
method is telling the query builder that "when" there is a email being provided in our request we want to apply the query fn($query) => $query->where('email', 'regexp', $this->request->email)
which will search for any email addresses that contain any character provided by the "email" portion of the request.
We now need to add this filter to our pipeline. We'll do this by adding the fully qualified name to the $pipelines
array variable in our controller:
app/Http/Controllers/UserSearchController.php
1namespace App\Http\Controllers;23use App\Models\User;4use Illuminate\Http\Request;5use Illuminate\Support\Facades\Pipeline;67class UserSearchController extends Controller8{9 /**10 * Handle the incoming request.11 *12 * @param Request $request13 */14 public function __invoke(Request $request)15 {16 $pipelines = [17 \App\Filters\ByEmail::class18 ];1920 return Pipeline::send(User::query())21 ->through($pipelines)22 ->thenReturn()23 ->paginate();24 }25}
With our pipeline being aware of our filter, let's test this by visiting our API URL from earlier, but we'll be sure to add the email reference to our query string:
1http://yourdomain.test/api/users/search?email=.org
In my example I'm telling our endpoint we want to filter by email addresses which contain .org. As you'll see our results set now includes only records with email addresses containing '.org' addresses:
1{ 2 "current_page": 1, 3 "data": [ 4 { 5 "id": 1, 6 "name": "Clara Runte", 7 "email": "jmurazik@example.org", 8 "email_verified_at": "2023-03-16T20:50:38.000000Z", 9 "timezone": "America/Sitka", 10 "dob": "1995-12-14", 11 "created_at": "2023-03-16T20:50:39.000000Z", 12 "updated_at": "2023-03-16T20:50:39.000000Z" 13 }, 14 { 15 "id": 3, 16 "name": "Charlotte Gutkowski", 17 "email": "clifford.schumm@example.org", 18 "email_verified_at": "2023-03-16T20:50:39.000000Z", 19 "timezone": "Africa/Gaborone", 20 "dob": "1971-09-23", 21 "created_at": "2023-03-16T20:50:39.000000Z", 22 "updated_at": "2023-03-16T20:50:39.000000Z" 23 }, 24 { 25 "id": 4, 26 "name": "Mariana Hamill", 27 "email": "lbrakus@example.org", 28 "email_verified_at": "2023-03-16T20:50:39.000000Z", 29 "timezone": "Europe/Ljubljana", 30 "dob": "1989-05-13", 31 "created_at": "2023-03-16T20:50:39.000000Z", 32 "updated_at": "2023-03-16T20:50:39.000000Z" 33 }, 34 { 35 "id": 5, 36 "name": "Prof. Ima Zemlak", 37 "email": "heaven.konopelski@example.org", 38 "email_verified_at": "2023-03-16T20:50:39.000000Z", 39 "timezone": "America/Rio_Branco", 40 "dob": "1985-09-04", 41 "created_at": "2023-03-16T20:50:39.000000Z", 42 "updated_at": "2023-03-16T20:50:39.000000Z" 43 }, 44 { 45 "id": 9, 46 "name": "Darrel Barton", 47 "email": "casimer64@example.org", 48 "email_verified_at": "2023-03-16T20:50:39.000000Z", 49 "timezone": "America/Matamoros", 50 "dob": "1973-11-02", 51 "created_at": "2023-03-16T20:50:39.000000Z", 52 "updated_at": "2023-03-16T20:50:39.000000Z" 53 }, 54 { 55 "id": 10, 56 "name": "Prof. Darrick Kozey", 57 "email": "rosalee56@example.org", 58 "email_verified_at": "2023-03-16T20:50:39.000000Z", 59 "timezone": "Africa/Juba", 60 "dob": "2020-12-15", 61 "created_at": "2023-03-16T20:50:39.000000Z", 62 "updated_at": "2023-03-16T20:50:39.000000Z" 63 }, 64 { 65 "id": 14, 66 "name": "Lysanne Walter", 67 "email": "katheryn.tromp@example.org", 68 "email_verified_at": "2023-03-16T20:50:39.000000Z", 69 "timezone": "Asia/Urumqi", 70 "dob": "2004-06-27", 71 "created_at": "2023-03-16T20:50:39.000000Z", 72 "updated_at": "2023-03-16T20:50:39.000000Z" 73 }, 74 { 75 "id": 22, 76 "name": "Zula Hammes", 77 "email": "hill.rosie@example.org", 78 "email_verified_at": "2023-03-16T20:50:39.000000Z", 79 "timezone": "Pacific/Midway", 80 "dob": "2008-10-08", 81 "created_at": "2023-03-16T20:50:39.000000Z", 82 "updated_at": "2023-03-16T20:50:39.000000Z" 83 }, 84 { 85 "id": 23, 86 "name": "Brandon Reichert", 87 "email": "aliya.rohan@example.org", 88 "email_verified_at": "2023-03-16T20:50:39.000000Z", 89 "timezone": "Africa/Dakar", 90 "dob": "2022-01-14", 91 "created_at": "2023-03-16T20:50:39.000000Z", 92 "updated_at": "2023-03-16T20:50:39.000000Z" 93 }, 94 { 95 "id": 27, 96 "name": "Michele Labadie", 97 "email": "issac84@example.org", 98 "email_verified_at": "2023-03-16T20:50:39.000000Z", 99 "timezone": "America/Blanc-Sablon",100 "dob": "2003-08-25",101 "created_at": "2023-03-16T20:50:39.000000Z",102 "updated_at": "2023-03-16T20:50:39.000000Z"103 },104 {105 "id": 28,106 "name": "Dr. Erik Metz IV",107 "email": "jveum@example.org",108 "email_verified_at": "2023-03-16T20:50:39.000000Z",109 "timezone": "Africa/Luanda",110 "dob": "1971-05-16",111 "created_at": "2023-03-16T20:50:39.000000Z",112 "updated_at": "2023-03-16T20:50:39.000000Z"113 },114 {115 "id": 30,116 "name": "Macy Beier",117 "email": "nicolas.alexandrea@example.org",118 "email_verified_at": "2023-03-16T20:50:39.000000Z",119 "timezone": "Pacific/Pago_Pago",120 "dob": "1992-03-31",121 "created_at": "2023-03-16T20:50:39.000000Z",122 "updated_at": "2023-03-16T20:50:39.000000Z"123 },124 {125 "id": 33,126 "name": "Mrs. Donna Schuppe DDS",127 "email": "vblanda@example.org",128 "email_verified_at": "2023-03-16T20:50:39.000000Z",129 "timezone": "Atlantic/Canary",130 "dob": "2018-08-11",131 "created_at": "2023-03-16T20:50:39.000000Z",132 "updated_at": "2023-03-16T20:50:39.000000Z"133 },134 {135 "id": 40,136 "name": "Rebeka Hagenes V",137 "email": "torphy.paula@example.org",138 "email_verified_at": "2023-03-16T20:50:39.000000Z",139 "timezone": "Asia/Srednekolymsk",140 "dob": "1992-08-16",141 "created_at": "2023-03-16T20:50:39.000000Z",142 "updated_at": "2023-03-16T20:50:39.000000Z"143 },144 {145 "id": 42,146 "name": "Rey Zieme",147 "email": "ilehner@example.org",148 "email_verified_at": "2023-03-16T20:50:39.000000Z",149 "timezone": "Asia/Tehran",150 "dob": "1981-05-31",151 "created_at": "2023-03-16T20:50:39.000000Z",152 "updated_at": "2023-03-16T20:50:39.000000Z"153 }154 ],155 "first_page_url": "http://teachinglaravel.test/users/search?page=1",156 "from": 1,157 "last_page": 24,158 "last_page_url": "http://teachinglaravel.test/users/search?page=24",159 "links": [160 {161 "url": null,162 "label": "« Previous",163 "active": false164 },165 {166 "url": "http://teachinglaravel.test/users/search?page=1",167 "label": "1",168 "active": true169 },170 {171 "url": "http://teachinglaravel.test/users/search?page=2",172 "label": "2",173 "active": false174 },175 {176 "url": "http://teachinglaravel.test/users/search?page=3",177 "label": "3",178 "active": false179 },180 {181 "url": "http://teachinglaravel.test/users/search?page=4",182 "label": "4",183 "active": false184 },185 {186 "url": "http://teachinglaravel.test/users/search?page=5",187 "label": "5",188 "active": false189 },190 {191 "url": "http://teachinglaravel.test/users/search?page=6",192 "label": "6",193 "active": false194 },195 {196 "url": "http://teachinglaravel.test/users/search?page=7",197 "label": "7",198 "active": false199 },200 {201 "url": "http://teachinglaravel.test/users/search?page=8",202 "label": "8",203 "active": false204 },205 {206 "url": "http://teachinglaravel.test/users/search?page=9",207 "label": "9",208 "active": false209 },210 {211 "url": "http://teachinglaravel.test/users/search?page=10",212 "label": "10",213 "active": false214 },215 {216 "url": null,217 "label": "...",218 "active": false219 },220 {221 "url": "http://teachinglaravel.test/users/search?page=23",222 "label": "23",223 "active": false224 },225 {226 "url": "http://teachinglaravel.test/users/search?page=24",227 "label": "24",228 "active": false229 },230 {231 "url": "http://teachinglaravel.test/users/search?page=2",232 "label": "Next »",233 "active": false234 }235 ],236 "next_page_url": "http://teachinglaravel.test/users/search?page=2",237 "path": "http://teachinglaravel.test/users/search",238 "per_page": 15,239 "prev_page_url": null,240 "to": 15,241 "total": 352242}
Now that we understand what's going on we'll create 2 more filters which will allow us to search by name and dob.
app/Filters/ByName.php
1namespace App\Filters;23use Closure;4use Illuminate\Database\Eloquent\Builder;5use Illuminate\Http\Request;67class ByName8{9 public function __construct(public Request $request){}1011 public function handle(Builder $query, Closure $next)12 {13 return $next($query)14 ->when($this->request->has('name'),15 fn($query) => $query->where('name', 'regexp', $this->request->name)16 );17 }18}
app/Filters/ByDob.php
1namespace App\Filters;23use Closure;4use Illuminate\Database\Eloquent\Builder;5use Illuminate\Http\Request;67class ByDob8{9 public function __construct(public Request $request){}1011 public function handle(Builder $query, Closure $next)12 {13 return $next($query)14 ->when($this->request->has('dob'),15 fn($query) => $query->where('dob', 'regexp', $this->request->dob)16 );17 }18}
I bet you've spotted a recurring pattern in our approach. Challenge yourself by creating a way to make the code reusable. Then share with me on Twitter what you did 😀
Let's incorporate them into our controller:
app/Http/Controllers/UserSearchController.php
1namespace App\Http\Controllers;23use App\Models\User;4use Illuminate\Http\Request;5use Illuminate\Support\Facades\Pipeline;67class UserSearchController extends Controller8{9 /**10 * Handle the incoming request.11 *12 * @param Request $request13 */14 public function __invoke(Request $request)15 {16 $pipelines = [17 \App\Filters\ByEmail::class,18 \App\Filters\ByName::class,19 \App\Filters\ByDob::class,20 ];2122 return Pipeline::send(User::query())23 ->through($pipelines)24 ->thenReturn()25 ->paginate();26 }27}
What's really cool now is that we can stack these filters in our request. For example, lets search for .org addresses where the name contains the letter R and is born in the year 1981.
1http://yourdomain.test/api/users/search?email=.org&name=R&dob=1981
1{ 2 "current_page": 1, 3 "data": [ 4 { 5 "id": 42, 6 "name": "Rey Zieme", 7 "email": "ilehner@example.org", 8 "email_verified_at": "2023-03-16T20:50:39.000000Z", 9 "timezone": "Asia/Tehran",10 "dob": "1981-05-31",11 "created_at": "2023-03-16T20:50:39.000000Z",12 "updated_at": "2023-03-16T20:50:39.000000Z"13 },14 {15 "id": 84,16 "name": "Clinton Hettinger",17 "email": "walter.vilma@example.org",18 "email_verified_at": "2023-03-16T20:50:39.000000Z",19 "timezone": "Africa/Malabo",20 "dob": "1981-03-01",21 "created_at": "2023-03-16T20:50:39.000000Z",22 "updated_at": "2023-03-16T20:50:39.000000Z"23 },24 {25 "id": 197,26 "name": "Tyrique McDermott Sr.",27 "email": "cloyd.jast@example.org",28 "email_verified_at": "2023-03-16T20:50:39.000000Z",29 "timezone": "America/Montevideo",30 "dob": "1981-07-13",31 "created_at": "2023-03-16T20:50:39.000000Z",32 "updated_at": "2023-03-16T20:50:39.000000Z"33 },34 {35 "id": 219,36 "name": "Dr. Patsy Hoeger",37 "email": "smitham.audra@example.org",38 "email_verified_at": "2023-03-16T20:50:39.000000Z",39 "timezone": "Europe/Bratislava",40 "dob": "1981-02-03",41 "created_at": "2023-03-16T20:50:39.000000Z",42 "updated_at": "2023-03-16T20:50:39.000000Z"43 },44 {45 "id": 877,46 "name": "Mrs. Laisha Reichel MD",47 "email": "leonor42@example.org",48 "email_verified_at": "2023-03-16T20:50:39.000000Z",49 "timezone": "Pacific/Niue",50 "dob": "1981-09-20",51 "created_at": "2023-03-16T20:50:39.000000Z",52 "updated_at": "2023-03-16T20:50:39.000000Z"53 }54 ],55 "first_page_url": "http://teachinglaravel.test/users/search?page=1",56 "from": 1,57 "last_page": 1,58 "last_page_url": "http://teachinglaravel.test/users/search?page=1",59 "links": [60 {61 "url": null,62 "label": "« Previous",63 "active": false64 },65 {66 "url": "http://teachinglaravel.test/users/search?page=1",67 "label": "1",68 "active": true69 },70 {71 "url": null,72 "label": "Next »",73 "active": false74 }75 ],76 "next_page_url": null,77 "path": "http://teachinglaravel.test/users/search",78 "per_page": 15,79 "prev_page_url": null,80 "to": 5,81 "total": 582}
In conclusion, Laravel pipelines are a powerful tool that can simplify your code and streamline your workflow. By breaking down complex processes into small, manageable steps, pipelines make it easier to build scalable and maintainable applications.
Whether you're working with data transformations, API requests, or any other type of data processing, Laravel pipelines provide an elegant and efficient way to handle the flow of data through your application. By using the techniques outlined in this article, you can harness the power of pipelines to take your Laravel development to the next level.
So don't be afraid to give pipelines a try! With their flexible and customizable architecture, you can build pipelines that are tailored to your specific needs and help you build high-quality, performant applications with ease. Happy coding!