Building and Consuming APIs in Laravel: A Step-by-Step Guide

Nova Novriansyah
NovAI- PHP Laravel 101
6 min readJul 3, 2024

In today’s interconnected digital landscape, APIs (Application Programming Interfaces) are crucial for facilitating seamless communication between applications. Laravel, known for its elegance and robustness in web development, offers powerful tools for both creating and consuming RESTful APIs. This article provides a comprehensive guide, complete with a sample project, to help you master API development in Laravel.

Introduction to RESTful APIs

REST (Representational State Transfer) is an architectural style that defines a set of constraints for creating web services. RESTful APIs adhere to these principles, utilizing standard HTTP methods like GET, POST, PUT, and DELETE for data manipulation. Laravel’s framework simplifies the process of building RESTful APIs by providing intuitive routing, controllers, and middleware.

Sample Project: Building a Blog API

Let’s create a simple blog API using Laravel, where we can manage posts and comments. Follow these steps to develop and consume this API.

Step 1: Setup Laravel Project

First, ensure you have Composer installed. Create a new Laravel project named blog-api:

composer create-project --prefer-dist laravel/laravel blog-api
cd blog-api

Create new postgresql named simple_web_api_db on your server.

Update your .env file with PostgreSQL database credentials:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=simple_web_api_db
DB_USERNAME=postgres
DB_PASSWORD=zuruck

Step 2: Define API Routes

Define API routes in routes/api.php to handle CRUD operations for posts and comments:

// routes/api.php

use App\Http\Controllers\API\PostController;
use App\Http\Controllers\API\CommentController;

Route::apiResource('posts', PostController::class);
Route::apiResource('posts.comments', CommentController::class)->shallow();

Step 3: Create Models and Migrations

Generate models and migrations for Post and Comment using Artisan commands:

php artisan make:model Post -m
php artisan make:model Comment -m

Define relationships in migrations and models (app/Models/Post.php and app/Models/Comment.php).

Define relationships in migrations and models.

Posts Migration

// database/migrations/xxxx_xx_xx_create_posts_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}

Comments Migration

// database/migrations/xxxx_xx_xx_create_comments_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCommentsTable extends Migration
{
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->onDelete('cascade');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('comments');
}
}

Post Model

// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'content'];
public function comments()
{
return $this->hasMany(Comment::class);
}
}

Comment Model

// app/Models/Comment.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use HasFactory;
protected $fillable = ['post_id', 'content'];
public function post()
{
return $this->belongsTo(Post::class);
}
}

Step 4: Implement Controllers

Create controllers for Post and Comment to handle CRUD operations:

<?
// app/Http/Controllers/API/PostController.php

namespace App\Http\Controllers\API;

use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
public function index()
{
return Post::with('comments')->get();
}

public function store(Request $request)
{
$post = Post::create($request->all());
return response()->json($post, 201);
}

public function show(Post $post)
{
return $post->load('comments');
}

public function update(Request $request, Post $post)
{
$post->update($request->all());
return response()->json($post, 200);
}

public function destroy(Post $post)
{
$post->delete();
return response()->json(null, 204);
}
}
<?
// app/Http/Controllers/API/CommentController.php

namespace App\Http\Controllers\API;

use App\Models\Comment;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class CommentController extends Controller
{
public function index($postId)
{
return Comment::where('post_id', $postId)->get();
}

public function store(Request $request, $postId)
{
$comment = new Comment();
$comment->post_id = $postId;
$comment->content = $request->input('content');
$comment->save();

return response()->json($comment, 201);
}

public function show($postId, Comment $comment)
{
return $comment;
}

public function update(Request $request, $postId, Comment $comment)
{
$comment->update($request->all());
return response()->json($comment, 200);
}

public function destroy($postId, Comment $comment)
{
$comment->delete();
return response()->json(null, 204);
}
}

Step 5: Implement API Authentication

Secure the API using Laravel Sanctum for token-based authentication. Install Sanctum and configure it:

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Implement token authentication in your PostController or a dedicated AuthController.

Step 6: Testing the API

to run to api, run this on the terminal:

php artisan serve

Populate with dummy data

Insert Dummy Data into posts Table

INSERT INTO posts (title, content, created_at, updated_at) VALUES
('First Post', 'This is the content of the first post.', NOW(), NOW()),
('Second Post', 'This is the content of the second post.', NOW(), NOW()),
('Third Post', 'This is the content of the third post.', NOW(), NOW()),
('Fourth Post', 'This is the content of the fourth post.', NOW(), NOW()),
('Fifth Post', 'This is the content of the fifth post.', NOW(), NOW()),
('Sixth Post', 'This is the content of the sixth post.', NOW(), NOW()),
('Seventh Post', 'This is the content of the seventh post.', NOW(), NOW()),
('Eighth Post', 'This is the content of the eighth post.', NOW(), NOW()),
('Ninth Post', 'This is the content of the ninth post.', NOW(), NOW()),
('Tenth Post', 'This is the content of the tenth post.', NOW(), NOW());

Insert Dummy Data into comments Table

We will add comments for each of the 10 posts, ensuring referential integrity by using the correct post_id.

INSERT INTO comments (post_id, content, created_at, updated_at) VALUES
(1, 'This is a comment on the first post.', NOW(), NOW()),
(1, 'This is another comment on the first post.', NOW(), NOW()),
(2, 'This is a comment on the second post.', NOW(), NOW()),
(2, 'This is another comment on the second post.', NOW(), NOW()),
(3, 'This is a comment on the third post.', NOW(), NOW()),
(3, 'This is another comment on the third post.', NOW(), NOW()),
(4, 'This is a comment on the fourth post.', NOW(), NOW()),
(4, 'This is another comment on the fourth post.', NOW(), NOW()),
(5, 'This is a comment on the fifth post.', NOW(), NOW()),
(5, 'This is another comment on the fifth post.', NOW(), NOW()),
(6, 'This is a comment on the sixth post.', NOW(), NOW()),
(6, 'This is another comment on the sixth post.', NOW(), NOW()),
(7, 'This is a comment on the seventh post.', NOW(), NOW()),
(7, 'This is another comment on the seventh post.', NOW(), NOW()),
(8, 'This is a comment on the eighth post.', NOW(), NOW()),
(8, 'This is another comment on the eighth post.', NOW(), NOW()),
(9, 'This is a comment on the ninth post.', NOW(), NOW()),
(9, 'This is another comment on the ninth post.', NOW(), NOW()),
(10, 'This is a comment on the tenth post.', NOW(), NOW()),
(10, 'This is another comment on the tenth post.', NOW(), NOW());

To test the API endpoints, you can use tools like Postman or directly from your browser:

Testing from Browser:

  • Simply enter the API endpoint in your browser’s address bar and append the required parameters for GET requests. For example:
  • http://your-api-domain/api/posts (GET request to fetch all posts)
  • http://your-api-domain/api/posts/{id} (GET request to fetch a specific post)
  • Ensure your Laravel development server (php artisan serve) is running to handle these requests.

Step 7: Consume the API

To consume the API from another Laravel application or a client application (e.g., Vue.js, React), use Laravel’s HTTP client:

use Illuminate\Support\Facades\Http;

$response = Http::get('http://your-api-domain/api/posts');
$posts = $response->json();

Conclusion

Building and consuming APIs in Laravel opens up endless possibilities for integrating applications, sharing data securely, and building scalable systems. By following the steps outlined in this guide and utilizing Laravel’s powerful features, you can streamline development processes and enhance application interoperability. Start building your APIs today and empower your applications with seamless connectivity.

--

--

Nova Novriansyah
NovAI- PHP Laravel 101

C|CISO, CEH, CC, CVA,CertBlockchainPractitioner, Google Machine Learning , Tensorflow, Unity Cert, Arduino Cert, AWS Arch Cert. CTO, IT leaders. Platform owners