loading...

How to consume RESTful APIs in Laravel 8 and Laravel 7

kingsconsult profile image Kingsconsult ・5 min read

Today, I am going to show you how to consume RESTful APIs, in my previous post I discuss How to Create a Secure CRUD RESTful API in Laravel 8 and 7 Using Laravel Passport, the article teaches you how to create a RESTful API and also securing the API with Passport, Laravel Passport is the official OAuth2 server for Laravel apps. It provides you with a full OAuth2 server implementation.
But in this article, we are only going to be discussing how to consume external API. Why some APIs are authenticated which will require providing a token in order to access the API, others are not authenticated, which means you can access the API without a token.
This article will show you how to implement the two instances. We are going to be using the code from my previous article Laravel 8 CRUD App, A simple guide, this is the GitHub repo for the code snippets.

Click on my profile to follow me to get more updates.

Step 1: Setup the app

  1. git clone https://github.com/Kingsconsult/laravel_8_crud.git
  2. cd laravel_8_crud/
  3. composer install
  4. npm install
  5. cp .env.example .env
  6. php artisan key:generate
  7. Add your database config in the .env file (you can check my articles on how to achieve that)
  8. php artisan migrate
  9. php artisan serve (if the server opens up, http://127.0.0.1:8000, then we are good to go) localhost
  10. Navigate to http://127.0.0.1:8000/projects

Step 2: Make sure Guzzle package is installed

By default, Laravel automatically includes this Guzzle as a dependency when you install Laravel, check your composer.json, if it is one of the required dependency, if you did not see it, or you want to update

composer require guzzlehttp/guzzle

Step 3: Create routes

Modify the routes/web.php file to this

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProjectController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::prefix('projects')->group(function () {
    Route::get('apiwithoutkey', [ProjectController::class, 'apiWithoutKey'])->name('apiWithoutKey');
    Route::get('apiwithkey', [ProjectController::class, 'apiWithKey'])->name('apiWithKey');
});


Route::resource('projects', ProjectController::class);
Enter fullscreen mode Exit fullscreen mode

We added two get routes, one for an API without key (unauthorized) and another with key (authorized).

Step 4: Create Controller methods

In our routes, we indicate that we have two more routes, so we need to write the methods, go to app/Http/Controller/ProjectController.php, and add the following methods
First, call the Guzzle class before the controller class, directly under the namespace

use GuzzleHttp\Client;


    public function apiWithoutKey()
    {
        $client = new Client(); //GuzzleHttp\Client
        $url = "https://api.github.com/users/kingsconsult/repos";


        $response = $client->request('GET', $url, [
            'verify'  => false,
        ]);

        $responseBody = json_decode($response->getBody());

        return view('projects.apiwithoutkey', compact('responseBody'));
    }

    public function apiWithKey()
    {
        $client = new Client();
        $url = "https://dev.to/api/articles/me/published";

        $params = [
            //If you have any Params Pass here
        ];

        $headers = [
            'api-key' => 'k3Hy5qr73QhXrmHLXhpEh6CQ'
        ];

        $response = $client->request('GET', $url, [
            // 'json' => $params,
            'headers' => $headers,
            'verify'  => false,
        ]);

        $responseBody = json_decode($response->getBody());

        return view('projects.apiwithkey', compact('responseBody'));
    }
Enter fullscreen mode Exit fullscreen mode

Explanation

  1. I instantiate the client class from guzzle.
  2. I assign the API URL to a variable (I used GitHub API for my public repositories, this is a public API that fetches one's public GitHub repositories), this API does not require a token for authorization.
  3. I use the request method of the client, it accepts 3 parameters ($method, $url, $options), the $options is where we pass our token if the API requires one, also I passed another option, verify, to be false.
  4. Finally, I convert my response to a json format, so I can pass it to the view.

The second method is for an API that requires authorization, I used dev.to API, this API fetches all my published articles and also all the stats for each article, I passed the api key to the options, I assigned it to a variable call headers.

Step 5: Create the views

I created separate views for the two API

resources/views/projects/apiwithoutkey.blade.php

@extends('layouts.app')

@section('content')

<style>


</style>
<div class="row mb-3">
    <div class="col-lg-12 margin-tb">
        <div class="text-center">
            <h2>Github Public Repository</h2>
            <a class="btn btn-primary" href="{{ route('projects.index') }}" title="Go back"> <i class="fas fa-backward fa-2x"></i> </a>
        </div>
    </div>
</div>



<div class="container-fluid mb-5" style="margin-bottom: 150px !important">
    <div class="row mr-4">
        @foreach ($responseBody as $response)

        <div class="col-xl-3 col-md-6 mb-4 hvr-grow ">
            <a href="{{ $response->html_url }}" class="text-muted">
                <div class="card shadow  py-0 rounded-lg ">
                    <div class="card-body py-2 px-2">
                        <div class="row no-gutters align-items-center">
                            <div class="col mr-2">
                                <div class=" font-weight-bold mb-4 mt- 2 text-primary text-center text-uppercase mb-1">
                                    {{ $response->name }}
                                </div>
                                <div class="h6 mb-0 text-gray-800 text-center">{{ $response->description }}
                                    @if ($response->description == null)
                                    {{ $response->name }}
                                    @endif
                                </div>
                            </div>
                        </div>

                        <div style="position: absolute; bottom: 0" class="mb-2"> <strong>
                                <hi>Language : {{ $response->language }}
                            </strong></hi>
                        </div>
                    </div>
                </div>
            </a>
        </div>
        @endforeach
    </div>
</div>

@endsection
Enter fullscreen mode Exit fullscreen mode

resources/views/projects/apiwithkey.blade.php

@extends('layouts.app')

@section('content')

<style>


</style>
<div class="row mb-3">
    <div class="col-lg-12 margin-tb">
        <div class="text-center">
            <h2>Dev.to Article stats</h2>
            <a class="btn btn-primary" href="{{ route('projects.index') }}" title="Go back"> <i class="fas fa-backward fa-2x"></i> </a>
        </div>
    </div>
</div>



<div class="container-fluid mb-5" style="margin-bottom: 150px !important">
    <div class="row mr-4">
        @foreach ($responseBody as $response)

        <div class="col-xl-3 col-md-6 mb-4 hvr-grow ">
            <div class="card shadow  py-0 rounded-lg ">
                <div class="card-body py-2">
                    <div class="row no-gutters align-items-center">
                        <div class="col mr-2">
                            <a href="{{ $response->url }}" class="text-muted">
                                <div class=" font-weight-bold mb-2 mt-2 text-primary text-center text-uppercase mb-1">
                                    {{ Str::limit($response->title, 45) }}

                                </div>
                            </a>
                            <div class="h6 mb-0 text-gray-800 text-center">
                                {{ Str::limit($response->description, 100) }}
                            </div>
                        </div>
                    </div>
                    <div style="position: absolute; bottom: 0" class="mb-2">
                        <hi>Page Views: <strong>{{ number_format($response->page_views_count) }}</strong></hi>
                        <hi class="ml-3"> Reactions: <strong>{{ $response->positive_reactions_count }} </strong></hi>
                    </div>
                </div>
            </div>
        </div>
        @endforeach
    </div>
</div>

@endsection
Enter fullscreen mode Exit fullscreen mode

Testing
Go to the index page of projects http://127.0.0.1:8000/projects
http://127.0.0.1:8000/projects

http://127.0.0.1:8000/projects/apiwithkey
API with key

http://127.0.0.1:8000/projects/apiwithoutkey
API without key

You can get the complete code from the repo.
Follow me for more of my articles, you can leave comments, suggestions, and reactions

click the link to view my profile and follow me

Visit my other posts

Discussion

pic
Editor guide