174

What I want is get an object from an API with a HTTP (eg, jQuery's AJAX) request to an external api. How do I start? I did research on Mr Google but I can't find anything helping.

Im starting to wonder is this is even possible? In this post Laravel 4 make post request from controller to external url with data it looks like it can be done. But there's no example nor any source where to find some documentation.

Please help me out?

Community
  • 1
  • 1
Chilion
  • 3,870
  • 4
  • 30
  • 48

9 Answers9

214

Based upon an answer of a similar question here: https://stackoverflow.com/a/22695523/1412268

Take a look at Guzzle

$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', ['auth' =>  ['user', 'pass']]);
echo $res->getStatusCode(); // 200
echo $res->getBody(); // { "type": "User", ....
Community
  • 1
  • 1
AI Snoek
  • 2,286
  • 2
  • 13
  • 8
101

We can use package Guzzle in Laravel, it is a PHP HTTP client to send HTTP requests.

You can install Guzzle through composer

composer require guzzlehttp/guzzle:~6.0

Or you can specify Guzzle as a dependency in your project's existing composer.json

{
   "require": {
      "guzzlehttp/guzzle": "~6.0"
   }
}

Example code in laravel 5 using Guzzle as shown below,

use GuzzleHttp\Client;
class yourController extends Controller {

    public function saveApiData()
    {
        $client = new Client();
        $res = $client->request('POST', 'https://url_to_the_api', [
            'form_params' => [
                'client_id' => 'test_id',
                'secret' => 'test_secret',
            ]
        ]);
        echo $res->getStatusCode();
        // 200
        echo $res->getHeader('content-type');
        // 'application/json; charset=utf8'
        echo $res->getBody();
        // {"type":"User"...'
}
Kenny Horna
  • 9,846
  • 3
  • 30
  • 58
Mohammed Safeer
  • 17,481
  • 8
  • 66
  • 74
  • 2
    Thank you for your answer. Also see my comment below my post; Long time later, created a really small tut how to use Guzzle. From aisnoek his answer. chilion.nl/laravel-post-requests-with-guzzle – Chilion Aug 19 at 12:09 √ – Chilion Sep 14 '15 at 19:27
  • 1
    Your comment `// "200"` should be `// 200` because the returned value is an integer. – mechanicious May 25 '18 at 07:08
59

You just want to call an external URL and use the results? PHP does this out of the box, if we're talking about a simple GET request to something serving JSON:

$json = json_decode(file_get_contents('http://host.com/api/stuff/1'), true);

If you want to do a post request, it's a little harder but there's loads of examples how to do this with curl.

So I guess the question is; what exactly do you want?

Bram
  • 3,231
  • 13
  • 19
  • I want to be able to use all kinds of functions of an REST API. So yes, I will need POST. I thought (hoped...) that Laravel would have some methods to do it in a Laravel kinda way, but I'll stick to PHP then. Thanks. – Chilion Mar 12 '14 at 23:11
  • If you do not need the result, just trying to HIT the API or PING a URL, this is the best approach. Thanks :) – Rafik Farhad Aug 21 '19 at 10:59
25

As of Laravel v7.X, the framework now comes with a minimal API wrapped around the Guzzle HTTP client. It provides an easy way to make get, post, put, patch, and delete requests using the HTTP Client:

use Illuminate\Support\Facades\Http;

$response = Http::get('http://test.com');
$response = Http::post('http://test.com');
$response = Http::put('http://test.com');
$response = Http::patch('http://test.com');
$response = Http::delete('http://test.com');

You can manage responses using the set of methods provided by the Illuminate\Http\Client\Response instance returned.

$response->body() : string;
$response->json() : array;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;

Please note that you will, of course, need to install Guzzle like so:

composer require guzzlehttp/guzzle

There are a lot more helpful features built-in and you can find out more about these set of the feature here: https://laravel.com/docs/7.x/http-client

This is definitely now the easiest way to make external API calls within Laravel.

Syclone
  • 799
  • 9
  • 12
9

Updated on March 21 2019

Add GuzzleHttp package using composer require guzzlehttp/guzzle:~6.3.3

Or you can specify Guzzle as a dependency in your project's composer.json

{
   "require": {
      "guzzlehttp/guzzle": "~6.3.3"
   }
}

Include below line in the top of the class where you are calling the API

use GuzzleHttp\Client;

Add below code for making the request

$client = new Client();

$res = $client->request('POST', 'http://www.exmple.com/mydetails', [
    'form_params' => [
        'name' => 'george',
    ]
]);

if ($res->getStatusCode() == 200) { // 200 OK
    $response_data = $res->getBody()->getContents();
}
mujuonly
  • 6,482
  • 5
  • 30
  • 59
5

Definitively, for any PHP project, you may want to use GuzzleHTTP for sending requests. Guzzle has very nice documentation you can check here. I just want to say that, you probably want to centralize the usage of the Client class of Guzzle in any component of your Laravel project (for example a trait) instead of being creating Client instances on several controllers and components of Laravel (as many articles and replies suggest).

I created a trait you can try to use, which allows you to send requests from any component of your Laravel project, just using it and calling to makeRequest.

namespace App\Traits;
use GuzzleHttp\Client;
trait ConsumesExternalServices
{
    /**
     * Send a request to any service
     * @return string
     */
    public function makeRequest($method, $requestUrl, $queryParams = [], $formParams = [], $headers = [], $hasFile = false)
    {
        $client = new Client([
            'base_uri' => $this->baseUri,
        ]);

        $bodyType = 'form_params';

        if ($hasFile) {
            $bodyType = 'multipart';
            $multipart = [];

            foreach ($formParams as $name => $contents) {
                $multipart[] = [
                    'name' => $name,
                    'contents' => $contents
                ];
            }
        }

        $response = $client->request($method, $requestUrl, [
            'query' => $queryParams,
            $bodyType => $hasFile ? $multipart : $formParams,
            'headers' => $headers,
        ]);

        $response = $response->getBody()->getContents();

        return $response;
    }
}

Notice this trait can even handle files sending.

If you want more details about this trait and some other stuff to integrate this trait to Laravel, check this article. Additionally, if interested in this topic or need major assistance, you can take my course which guides you in the whole process.

I hope it helps all of you.

Best wishes :)

JuanDMeGon
  • 1,001
  • 9
  • 18
1

You can use Httpful :

Website : http://phphttpclient.com/

Github : https://github.com/nategood/httpful

Jeremie Ges
  • 2,505
  • 18
  • 35
  • Looks great, although it doesn't answer my question in fact about a Laravel kinda way, I will sure look into this. Thanks! – Chilion Nov 04 '14 at 13:43
  • 1
    Laravel haven't got this out of the box, but Laravel run under composer so you can use a lib like Httpful to get the job done. By the way you can use also http://requests.ryanmccue.info/ – Jeremie Ges Nov 11 '14 at 08:38
  • Laravel is under composer so any package is fair game. – kratos Aug 02 '16 at 17:36
1

Basic Solution for Laravel 8 is

use Illuminate\Support\Facades\Http;

$response = Http::get('http://example.com');

I had conflict between "GuzzleHTTP sending requests" and "Illuminate\Http\Request;" don't ask me why... [it's here to be searchable]

So looking for 1sec i found in Laravel 8 Doc...

**Guzzle is inside the Laravel 8 Http Request !**

https://laravel.com/docs/8.x/http-client#making-requests

as you can see

https://laravel.com/docs/8.x/http-client#introduction

Laravel provides an expressive, minimal API around the Guzzle HTTP client, allowing you to quickly make outgoing HTTP requests to communicate with other web applications. Laravel's wrapper around Guzzle is focused on its most common use cases and a wonderful developer experience.

It worked for me very well, have fun and if helpful point up!

0

I also created trait similar to @JuanDMeGonthat's that u can use anywhere in your project.Please check this out

trait ApiRequests
{
  
    public function get($url, $data = null)
    {
        try {
            $response = Http::get($this->base_url . $url, $data);
        } catch (\Exception $e) {
            info($e->getMessage());
            abort(503);
        }

        if ( $response->status() == 401) {
            throw new AuthenticationException();
        } else if (! $response->successful()) {
           abort(503);
        }

        return $response->json();
    }

    public function post($url, $data = [])
    {
        $token = session()->get('token');
        try {
            $response = Http::acceptJson()->withToken($token)->post($this->base_url . $url, $data);
        } catch (\Exception $e) {
            abort(503);
        }

        if ($response->status() == 401 && !request()->routeIs('login')) {
            throw new AuthenticationException();
        }

        return $response;
    }
 
}







class Controller extends BaseController
{
    protected $base_url;
 
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests, ApiRequests;

    public function __construct()
    {
        $this->base_url = env("BASE_URL","http://192.168.xxxxxxx");
        
        View::share('base_url', $this->base_url);
       
    }


   
}
Matt
  • 26,570
  • 19
  • 63
  • 74