How to consume RESTful APIs in Laravel 8 and Laravel 7
Tags: php, laravel, beginners, webdev
Published: 2020-10-28 03:50:55

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](https://dev.to/kingsconsult/how-to-create-a-secure-crud-restful-api-in-laravel-8-and-7-using-laravel-passport-31fh), 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](https://dev.to/kingsconsult/laravel-8-crud-bi9), this is the [GitHub repo](https://github.com/Kingsconsult/laravel_8_crud)  for the code snippets. 

Click on my [profile](https://dev.to/kingsconsult) 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](https://res.cloudinary.com/kingsconsult/image/upload/v1600705305/laravel%208%20modal/4_pp7r76.png)
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);
```
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'));
    }
```
**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
```
**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
```
**Testing**
Go to the index page of projects **http://127.0.0.1:8000/projects**
![http://127.0.0.1:8000/projects](https://res.cloudinary.com/kingsconsult/image/upload/v1603855412/laravel%208%20consume%20api/2_at7edn.png)

**http://127.0.0.1:8000/projects/apiwithkey**
![API with key](https://res.cloudinary.com/kingsconsult/image/upload/v1603855412/laravel%208%20consume%20api/4_yvdsfo.png)

**http://127.0.0.1:8000/projects/apiwithoutkey**
![API without key](https://res.cloudinary.com/kingsconsult/image/upload/v1603855412/laravel%208%20consume%20api/1_mkit1h.png)

You can get the complete code from the [repo](https://github.com/Kingsconsult/laravel_8_consume_api).
Follow me for more of my articles, you can leave comments, suggestions, and reactions

 [click the link to view my profile and follow me] (https://dev.to/kingsconsult)

Visit my other posts 
{% link https://dev.to/kingsconsult/how-to-create-a-secure-crud-restful-api-in-laravel-8-and-7-using-laravel-passport-31fh %}
{% link https://dev.to/kingsconsult/how-to-get-the-entire-country-list-in-laravel-8-downwards-ahb %}