REST API In Laravel

Websolutionstuff | Aug-26-2020 | Categories : Laravel PHP

In this article, we will explore the world of RESTful APIs in the context of Laravel, encompassing versions 8, 9, and 10. REST API, or Representational State Transfer Application Programming Interface, relies on HTTP requests to facilitate data operations like GET, PUT, POST, and DELETE.

Our tutorial will walk you through CRUD (Create, Read, Update, Delete) operations using REST API, shedding light on the creation of RESTful APIs with authentication, including the use of Laravel Passport, a powerful tool for user validation. We will also delve into the process of retrieving data through APIs.

Laravel simplifies the creation of APIs, particularly when incorporating authentication for mobile applications, thanks to Laravel Passport, which streamlines the generation of authentication tokens.

Let's embark on this journey to explore REST API, CRUD operations, and the art of crafting RESTful APIs in Laravel 8, 9, and 10

 Step 1: Install Laravel

Type the following command in the terminal to create a new project.

composer create-project --prefer-dist laravel/laravel REST_API

 

 

Step 2: Install Passport

Now, we need to install Passport using the Composer package manager. To do this, execute the following command in your terminal.

composer require laravel/passport

After installing the package, you need to obtain the default migration to create new Passport tables in your database. To do this, run the following command.

php artisan migrate

Now, let's install Passport using the passport:install command. This command generates token keys for enhanced security. Run the following command.

php artisan passport:install

 

Step 3: Passport Configuration

Now, we need to configure Passport in three places: the model, the service provider, and the auth configuration file.

1) HasApiTokens class of Passport has been added in the User model,

Add the below code in app/User.php

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable,HasApiTokens;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

 

 

2) In AuthServiceProvider we have added "Passport::routes()"

Add below code app/Providers/AuthServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

 

3) We have added api auth configuration in auth.php.

In config/auth.php add the below code.

<?php

return [

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',            
        ],
    ],
];

 

 

Step 4: Add Table and Model

In this step, we will create a migration for the Product table using the php artisan command. Run the following command in your terminal:

php artisan make:migration create_products_table

After running the aforementioned command, you will locate the migration in the following path: database/migrations. In your migration file, add the following code to create the products table.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('detail');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Now, run the below code in the terminal to create a migration.

php artisan migrate

And add the below code in the app/Product.php file

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'name', 'detail'
    ];
}

 

 

Step 5: Create API Routes

In step 5, we will create API routes. Laravel offers an api.php file for defining web service routes. Let's add a route in the routes/api.php file.

<?php

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

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

Route::post('register', 'API\RegisterController@register');
Route::post('login', 'API\RegisterController@login');
   
Route::middleware('auth:api')->group( function () {
    Route::resource('products', 'API\ProductController');
});

 

Step 6: Create Controller

 Now, I have created BaseController, ProductController, and RegisterController in api folder.

app/Http/Controllers/API/BaseController.php

<?php

namespace App\Http\Controllers\API;

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

class BaseController extends Controller
{
    public function sendResponse($result, $message)
    {
    	$response = [
            'success' => true,
            'data'    => $result,
            'message' => $message,
        ];
        return response()->json($response, 200);
    }

    public function sendError($error, $errorMessages = [], $code = 404)
    {
    	$response = [
            'success' => false,
            'message' => $error,
        ];

        if(!empty($errorMessages)){
            $response['data'] = $errorMessages;
        }
        
        return response()->json($response, $code);
    }

}

app/Http/Controllers/API/ProductController.php

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Product;
use Validator;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Http\Resources\Product as ProductResource;

class ProductController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $products = Product::all();

        return $this->sendResponse(ProductResource::collection($products), 'Products Retrieved Successfully.');
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $input = $request->all();
   
        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
   
        $product = Product::create($input);
   
        return $this->sendResponse(new ProductResource($product), 'Product Created Successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $product = Product::find($id);
  
        if (is_null($product)) {
            return $this->sendError('Product not found.');
        }
   
        return $this->sendResponse(new ProductResource($product), 'Product Retrieved Successfully.');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $input = $request->all();
   
        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
        $product = Product::find($id);   
        $product->name = $input['name'];
        $product->detail = $input['detail'];
        $product->save();
   
        return $this->sendResponse(new ProductResource($product), 'Product Updated Successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $product = Product::find($id);
        $product->delete();
   
        return $this->sendResponse([], 'Product Deleted Successfully.');
    }
}

 

 

app/Http/Controllers/API/RegisterController.php

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;

class RegisterController extends BaseController
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
   
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('MyApp')->accessToken;
        $success['name'] =  $user->name;
   
        return $this->sendResponse($success, 'User register successfully.');
    }

    public function login(Request $request)
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 
            $user = Auth::user(); 
            $success['token'] =  $user->createToken('MyApp')->accessToken; 
            $success['name'] =  $user->name;
            return $this->sendResponse($success, 'User login successfully.');
        } 
        else{ 
            return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
        } 
    }
}

 

Step 7: Create Eloquent API Resources

Now, we need to create API resources. Laravel's resource classes provide a convenient way to transform models and collections into JSON format in an expressive and straightforward manner.

php artisan make:resource Product

Now, a New file is created on this app/Http/Resources/Product.php path.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class Product extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'detail' => $this->detail,
            'created_at' => $this->created_at->format('d/m/Y'),
            'updated_at' => $this->updated_at->format('d/m/Y'),
        ];
    }
}

 

 

After implementing all the necessary code, we are prepared to run a full RESTful API in Laravel.

For testing and validation, we will use the POSTMAN API. POSTMAN is a versatile collaboration platform designed for API development. It offers a range of features that simplify each stage of API creation and enhance collaboration, ultimately speeding up the API development process.

To aid in your understanding, we have included screenshots and descriptions related to POSTMAN in this article.

First and foremost, you need to register on POSTMAN to explore and test our example

 

1 - Register API: Verb: GET, URL:http://localhost:8000/api/register

Laravel_rest_api_register

 

2 - After successfully registering in postman we need to add an access token in headers.

Add_accessToken

 

3 - Login API: Verb: GET, URL:http://localhost:8000/api/login

Laravel_rest_api_login 

4 - Create Product List API: Verb: GET, URL:http://localhost:8000/api/products

Laravel_rest_api_create

 

5 - Product Show API: Verb: GET, URL:http://localhost:8000/api/products/{id}

Laravel_rest_api_show 

6 - Product Update API: Verb: PUT, URL:http://localhost:8000/api/products/{id}

Laravel_rest_api_update 

7 - Product Delete API: Verb: DELETE, URL:http://localhost:8000/api/products/{id}

Laravel_rest_api_delete

Finally, We are done with our code and it's your time to implement it in your project.

 

Download Code From Github: Laravel-REST-API

 

Conclusion:

In conclusion, we have embarked on a journey to explore the world of RESTful APIs in Laravel, covering versions 8, 9, and 10. We have learned the essential steps to create robust and secure APIs, including the installation of Laravel Passport for enhanced authentication.

Our journey has included the creation of API routes, resource classes, and database migrations. We've leveraged the power of Laravel to transform our models and collections into JSON responses.

By following this comprehensive guide, you can confidently build, test, and manage RESTful APIs in your Laravel applications. Whether you're working on mobile apps, web services, or any project that requires data interaction, this knowledge will prove invaluable.

 


You might also like:

Recommended Post
Featured Post
Laravel 8 Form Class Not Found
Laravel 8 Form Class Not Found

In this small post, we will solve the laravel 8 form class not found error, many time we have received errors like the l...

Read More

Mar-12-2021

Laravel 9 Left Join Query Example
Laravel 9 Left Join Query Exam...

In this article, we will see the laravel 9 left join query example. laravel 9 left join eloquent returns all rows from t...

Read More

Mar-31-2022

How To Get env Variable In Controller Or Blade File
How To Get env Variable In Con...

In this tutorial, I will give you information on how to get the .env variable in the controller or file. Many times we n...

Read More

Jul-26-2020

How To Create Stacked Bar Chart In Laravel 9 Using Highcharts
How To Create Stacked Bar Char...

In this article, we will see how to create a dynamic stacked bar chart in laravel 9 using highchart. Here, we will...

Read More

Dec-30-2022