Kinsta
Posted on June 19, 2023
Laravel Eloquent is an easy way to interact with your database. It is an object-relational mapper (ORM) that simplifies the complexities of databases by providing a model to interact with tables.
As such, Laravel Eloquent has excellent tools for creating and testing APIs to support your development. Read on to see how easy it is to create and test APIs using Laravel.
You’ll start by creating a model that you can use to build the API and database table. Then, you’ll see how to add a controller as a business logic layer and a route to complete the API. You’ll then learn how to perform testing APIs using Postman before finally focusing on authentication and error handling.
Prerequisites
To get started, here’s what you’ll need:
Basic knowledge of APIs and PHP
API Basics
Start by creating a new Laravel project using composer
:
composer create-project laravel/laravel laravel-api-create-test
To start the server, execute the following command, which runs the application server on port 8000:
cd laravel-api-create-test
php artisan serve
You should see the following screen:
Then, create a model with a -m
flag for the migration using the code below:
php artisan make:model Product -m
Now upgrade the migration file to include the required field. Add title and description fields for the product model and these two table fields inside the database/migrations/{date_stamp}_create_products_table.php file.
$table->string('title');
$table->longText('description');
The next step is to make these fields fillable. Inside app/Models/Product.php, make title
and description
fillable fields.
protected $fillable = ['title', 'description'];
How To Create a Controller
Now, create a controller file for the product by executing the following command. This will create the app/Http/Controllers/Api/ProductController.php file.
php artisan make:controller Api\\ProductController --model=Product
Now, add the logic for creating and retrieving the products. Inside the index
method, add the following code to retrieve all the products:
$products = Product::all();
return response()->json([
'status' => true,
'products' => $products
]);
After that, you must add a StoreProductRequest
class for storing the new products in the database. Add the following class at the top of the same file.
public function store(StoreProductRequest $request)
{
$product = Product::create($request->all());
return response()->json([
'status' => true,
'message' => "Product Created successfully!",
'product' => $product
], 200);
}
Now, you’ll create the request, which you can do by executing the following command:
php artisan make:request StoreProductRequest
If you want to add validations, you can use the app/Http/Requests/StoreProductRequest.php file. For this demonstration, there are no validations.
How To Create a Route
The final step before testing the API is adding a route. To do so, add the following code inside the routes/api.php file. Add the use
statement at the beginning of the file and the Route
statement in the body:
use App\Http\Controllers\Api\ProductController;
Route::apiResource('products', ProductController::class);
Before you start testing the API, ensure that the products table is in your database. If it doesn’t exist, create one using a control panel like XAMPP. Alternatively, you can execute the following command to migrate the database:
php artisan migrate
How To Test an API
Before testing the API, ensure that the <code>authorize</code> method inside the app/Http/Requests/StoreProductRequest.php is set to return <code>true</code>.
Now, you can create a new product using Postman. Start by hitting a POST
request to this URL: http://127.0.0.1:8000/api/products/. Because it’s a POST
request for creating a new product, you must pass a JSON object with a title and description.
{
"title":"Apple",
"description":"Best Apples of the world"
}
Creating a new product in Postman
After clicking the Send button, you should see the following:
After clicking on Send
Now, fetch the created products using the GET
request. The URL is the same. The results will look like the following:
How To Authenticate an API Using Sanctum
Authentication is crucial when securing an API. Laravel makes it easy by providing the functionality of the Sanctum token, which you can use as middleware. It secures the API using tokens generated when the user logs in using the correct credentials. Remember that users can’t access the secured API without a token.
The first step to adding authentication is to add a Sanctum package using the code below:
composer require laravel/sanctum
Then, publish the Sanctum configuration file:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
After that, add Sanctum’s token as middleware. Inside the app/Http/Kernel.php file, use the following class and replace middlewareGroups
with the following code in the protected middleware groups’ API.
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
The next step is to create a UserController
and add the code to get the token to authenticate.
php artisan make:controller UserController
After creating the UserController
, navigate to the app/Http/Controllers/UserController.php file and replace the existing code with the following code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
//
function index(Request $request)
{
$user= User::where('email', $request->email)->first();
// print_r($data);
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
$token = $user->createToken('my-app-token')->plainTextToken;
$response = [
'user' => $user,
'token' => $token
];
return response($response, 201);
}
}
Before you can test the authentication, create a user employing seeders. The following command creates a UsersTableSeeder file.
php artisan make:seeder UsersTableSeeder
Inside the database/seeders/UsersTableSeeder.php file, replace the existing code with the following code to seed the user:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => 'John Doe',
'email' => 'john@doe.com',
'password' => Hash::make('password')
]);
}
}
Now run the seeder using this command:
php artisan db:seed --class=UsersTableSeeder
The last step left in the authentication flow is to use the created middleware to protect the route. Navigate to the routes/api.php file and add the products route inside the middleware.
use App\Http\Controllers\UserController;
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::apiResource('products', ProductController::class);
});
Route::post("login",[UserController::class,'index']);
After adding a route to the middleware, you’ll get an internal server error if you try to fetch the products.
But once you log in, get a token, and use it in the header, it will authenticate you and start working. You can send a POST request to http://127.0.0.1:8000/api/login with the following body:
{
"email":"john@doe.com",
"password":"password"
}
Use the token received as a Bearer token and add it as the Authorization header.
How To Handle API Errors
Whenever you send a request to the server, it responds. With the response, it also sends a status code according to the nature of the response. For example, a 200 status code indicates that the request has succeeded, and a 404 suggests that the server can’t find the requested resource.
However, a status code isn’t enough. A human-readable error message is required. Laravel comes with many ways to handle errors. You can use a try-catch block, the fallback method, or send a custom response. The following code you added to the UserController
demonstrates this.
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
Summary
Laravel’s Eloquent Model makes it effortless to create, validate, and test APIs. Its object-relational mapping provides a straightforward approach to interacting with the database.
Furthermore, acting as middleware, Laravel’s Sanctum token can help you to secure your APIs quickly.
And P.S., if you need further optimization, Kinsta’s Database Hosting solution simplifies setting up and managing databases for all your web projects.
Posted on June 19, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.