Laravel retrieving data from REST API

102,570

Solution 1

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.

Solution 2

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).

Solution 3

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);

}

Solution 4

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

Solution 5

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.

Share:
102,570
Tomkarho
Author by

Tomkarho

Updated on November 07, 2020

Comments

  • Tomkarho
    Tomkarho over 3 years

    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?

  • alexleonard
    alexleonard about 10 years
    I don't understand why the other answer is selected as the right answer. Surely the question is about querying a remote RESTful API not building one.
  • petercoles
    petercoles about 10 years
    The answer marked as correct shows how to build an app and protect an app to consume the API and save the data retrieved, so it does answer the question and go little beyond its scope, but in a quite specific way. However, I too prefer fideloper's answer as it's more generally (even with a specific package recommendation!)
  • errakeshpd
    errakeshpd almost 10 years
    if sending value as a json-array to the 'update()' want to save all fields from that array how we can do that instead of mentioning one by one..$page->title =$input['title'];$page->slug =$input['slug']; etc.?
  • Anshad Vattapoyil
    Anshad Vattapoyil almost 10 years
    @brito a simple solution foreach ($input as $key => $value) { $page->$key = $value; } this may work.
  • igorsantos07
    igorsantos07 almost 9 years
    Is this what was asked by the OP? It seems he asked about retrieving from and you answered about creating an API
  • Anshad Vattapoyil
    Anshad Vattapoyil almost 9 years
    @igorsantos07 Tried to explain complete step including retrieval.
  • igorsantos07
    igorsantos07 almost 9 years
    I couldn't see anywhere about how to create models to retrieve data from an API. All your answer is about creating an API and leveraging Laravel Resource controllers. That's hot what was asked.
  • JustAMartin
    JustAMartin over 8 years
    The question was "[..] retrieving data from a REST api [..] Does Laravel have a built in mechanism to retrieve data from external sources?" which leads me to think that it was asked how to call other web services from Laravel application. But the accepted answer described it from the other side - how to retrieve data from Laravel application using curl. And one note - do not run composer update blindly - it will update all your libraries, potentially breaking something. Always prefer using composer require vendor/library approach if you want to be stable.
  • rap-2-h
    rap-2-h over 8 years
    Buzz seems to be abandoned. Maybe you should use guzzle instead.
  • dollar
    dollar almost 8 years
    Even laravel document suggest using Guzzle while using mandrill or mailgun API's in project, and guzzle is easy to use and install.