Tomkarho
Tomkarho

Reputation: 1817

Laravel retrieving data from REST API

Okay so I have a following situation:

The system I am building is retrieving data from a REST api and saving that data into a database. What I am wondering is how could this be implemented and where would behaviour like this go in sense of Laravels structure (controller, model etc.)? Does Laravel have a built in mechanism to retrieve data from external sources?

Upvotes: 35

Views: 124779

Answers (6)

brc-dd
brc-dd

Reputation: 13044

While this question is tagged with Laravel 4, it still shows up on top of web searches. So posting the updated solution that works on newer Laravel versions.

Laravel now wraps the Guzzle HTTP client to provide you a built-in, more minimal API to create requests:

use Illuminate\Support\Facades\Http;
 
$response = Http::get('http://example.com');

This is available on Laravel 7 and above, but before Laravel 11, you need to manually install Guzzle:

composer require guzzlehttp/guzzle

Docs - https://laravel.com/docs/11.x/http-client

Upvotes: 0

fideloper
fideloper

Reputation: 12293

Edit: Buzz hasn't been updated for over a year, it's recomended to now use Guzzle, see Mohammed Safeer's answer.


I have used Buzz package in order to make API requests.

You can add this package by adding it to the require section in your composer.json file.

{
    require: {
        "kriswallsmith/buzz": "dev-master"
    }
}

Then run composer update to get it installed.

Then in Laravel you can wrap it in a class (perhaps a repository-like class) that handles making API request and returning data for your app to use.

<?php namespace My\App\Service;

class SomeApi {

    public function __construct($buzz)
    {
        $this->client = $buzz;
    }

    public function getAllWidgets()
    {
        $data = $this->client->get('http://api.example.com/all.json');
        // Do things with data, etc etc
    }

}

Note: This is pseudocode. You'll need to create a class that works for your needs, and do any fancy dependency injection or code architecture that you want/need.

As @Netbulae pointed out, a Repository might help you. The article he linked is a great place to start. The only difference between the article and what your code will do is that instead of using an Eloquent model to get your data from your database, you're making an API request and transforming the result into a set of arrays/objects that your application can use (Essentially, just the data storage is different, which is one of the benefits of bothering with a repository class in the first place).

Upvotes: 44

tsveti_iko
tsveti_iko

Reputation: 8032

You can choose what to use:

  1. Guzzle
  2. CURL
  3. file_get_contents :

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

Referrer

Upvotes: 9

Mohammed Safeer
Mohammed Safeer

Reputation: 21545

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',
            ]
        ]);

        $result= $res->getBody();
        dd($result);

}

Upvotes: 34

Anshad Vattapoyil
Anshad Vattapoyil

Reputation: 23483

First you have to make routes in your app/routes.php

/*
    API Routes
*/

Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function()
{
    Route::resource('pages', 'PagesController', array('only' => array('index', 'store', 'show', 'update', 'destroy')));
    Route::resource('users', 'UsersController');
});

Note: If you are not required authentication for API call, you can remove 'before' => 'auth.basic'

Here you can access index, store, show, update and destroy methods from your PagesController.

And the request urls will be,

GET http://localhost/project/api/v1/pages // this will call index function
POST http://localhost/project/api/v1/pages // this will call store function
GET http://localhost/project/api/v1/pages/1 // this will call show method with 1 as arg
PUT http://localhost/project/api/v1/pages/1 // this will call update with 1 as arg
DELETE http://localhost/project/api/v1/pages/1 // this will call destroy with 1 as arg

The command line CURL request will be like this (here the username and password are admin) and assumes that you have .htaccess file to remove index.php from url,

curl --user admin:admin localhost/project/api/v1/pages    
curl --user admin:admin -d 'title=sample&slug=abc' localhost/project/api/v1/pages
curl --user admin:admin localhost/project/api/v1/pages/2
curl -i -X PUT --user admin:admin -d 'title=Updated Title' localhost/project/api/v1/pages/2
curl -i -X DELETE --user admin:admin localhost/project/api/v1/pages/1

Next, you have two controllers named PagesController.php and UsersController.php in your app/controllers folder.

The PagesController.php,

<?php


class PagesController extends BaseController {


    /**
     * Display a listing of the resource.
     *
     * @return Response
     * curl --user admin:admin localhost/project/api/v1/pages
     */

    public function index() {

        $pages = Page::all();;

        return Response::json(array(
            'status' => 'success',
            'pages' => $pages->toArray()),
            200
        );
    }


    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     * curl --user admin:admin -d 'title=sample&slug=abc' localhost/project/api/v1/pages
     */

    public function store() {

        // add some validation also
        $input = Input::all();

        $page = new Page;

        if ( $input['title'] ) {
            $page->title =$input['title'];
        }
        if ( $input['slug'] ) {
            $page->slug =$input['slug'];
        }

        $page->save();

        return Response::json(array(
            'error' => false,
            'pages' => $page->toArray()),
            200
        );
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return Response
     * curl --user admin:admin localhost/project/api/v1/pages/2
     */

    public function show($id) {

        $page = Page::where('id', $id)
                    ->take(1)
                    ->get();

        return Response::json(array(
            'status' => 'success',
            'pages' => $page->toArray()),
            200
        );
    }


    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     * curl -i -X PUT --user admin:admin -d 'title=Updated Title' localhost/project/api/v1/pages/2
     */

    public function update($id) {

        $input = Input::all();

        $page = Page::find($id);

        if ( $input['title'] ) {
            $page->title =$input['title'];
        }
        if ( $input['slug'] ) {
            $page->slug =$input['slug'];
        }

        $page->save();

        return Response::json(array(
            'error' => false,
            'message' => 'Page Updated'),
            200
        );
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return Response
     * curl -i -X DELETE --user admin:admin localhost/project/api/v1/pages/1
     */

    public function destroy($id) {
        $page = Page::find($id);

        $page->delete();

        return Response::json(array(
            'error' => false,
            'message' => 'Page Deleted'),
            200
        );
    }

}

Then you have model named Page which will use table named pages.

<?php

class Page extends Eloquent {
}

You can use Laravel4 Generators to create these resources using php artisan generator command. Read here.

So using this route grouping you can use the same application to make API request and as a front-end.

Upvotes: 9

Skid Kadda
Skid Kadda

Reputation: 482

Try looking into the external API's manuals. There you will find info on how to retrieve information.

Then the best plan is to build an Interface. Check this out: http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories/

It's up to you how you use php to solve this.

Upvotes: 2

Related Questions