0

Looking to store a JSON response from an external API (using Guzzle) into mySQL database. A lot of what I've done so far is based on this question/answer

Storing parts of API data to database

I've got a model, controller and migration setup. The plan is to setup a CRON job that runs daily and calls for the new data from the API.

Right now, I just want to store the data into a database (I can setup the CRON job later).

Is there anything I'm missing here or any mistakes in my code? I had a route setup before but I don't know if that's applicable?

**EDIT

Nothing is being stored in the database when running this.

Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Rating extends Model
{

    protected $fillable = ['ratingId', 'ratingName', 'ratingKey', 'ratingKeyName', 'schemeTypeId'];

}

Controller

I've got two functions going on here. The first is consuming the external API. The second function is storing it into the database.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use GuzzleHttp\Client;
use App\Rating;


class GuzzleController extends Controller
{
    public function getRatings()
    {
        $client = new Client([
            'url' => 'https://api.ratings.food.gov.uk/ratings'
        ]);
        $request = $client->request('GET', [
            'headers' => [
                'x-api-version' => '2',
                'Accept'        => 'application/json'
            ]
        ]);

        $ratings = json_decode($request->getBody()->getContents(), true);
        return $ratings;

    }

    public function saveRatings()
    {
        $ratings = $this->getRatings();

        collect($ratings)
            ->each(function($rating, $key) {
                Rating::create([
                    'ratingid' => $rating['ratingid'],
                    'ratingName' => $rating['ratingName'],
                    'ratingKey' => $rating['ratingKey'],
                    'ratingKeyName' => $rating['ratingKeyName'],
                    'ratingTypeId' => $rating['ratingTypeId']
                ]);
            });

    }
}

Migrations

Just setting up the table here.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRatingsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('ratings', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('ratingId');
            $table->string('ratingName');
            $table->string('ratingKey');
            $table->string('ratingKeyName');
            $table->integer('schemeTypeId');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('ratings');
    }
}
6
  • What exactly is the problem? What are the errors you're getting? Commented Sep 4, 2019 at 20:56
  • Hey @CaddyDZ, updated description on this. But my database table remains empty. Is there a certain Artisan command I need to run after? Or any way to check for errors. Commented Sep 4, 2019 at 21:01
  • use dd() to narrow your problem scope for example check after Rating::create([]) compelet and see the result Commented Sep 4, 2019 at 21:23
  • Or maybe this is the reason Commented Sep 4, 2019 at 21:25
  • @HussamAdil thanks will give it a go! Commented Sep 4, 2019 at 21:28

1 Answer 1

0

I found a couple of small mistakes you made.

public function saveRatings()
    {
        $ratings = $this->getRatings();

        collect($ratings)
            ->each(function($rating, $key) {
                Rating::create([
                    'ratingId' => $rating['ratingId'],
                    'ratingName' => $rating['ratingName'],
                    'ratingKey' => $rating['ratingKey'],
                    'ratingKeyName' => $rating['ratingKeyName'],
                    'schemeTypeId' => $rating['schemeTypeId']
                ]);
            });
    }

'ratingTypeId' => $rating['ratingTypeId'] this was in your function but in migration you have $table->integer('schemeTypeId');

Your Guzzle request was not working for me. This is my version.

public function getRatings()
    {
        $url = 'https://api.ratings.food.gov.uk/ratings';

        $client = new Client(['headers' => [
            'x-api-version' => '2',
            'Accept'        => 'application/json'
        ]]);

        $request = $client->request('GET', $url);
        $ratings = json_decode($request->getBody()->getContents(), true);

        return $ratings['ratings'];
    }
Sign up to request clarification or add additional context in comments.

5 Comments

Hey Dino! Good spot and thanks for amending the request!. How would I go about testing this as a one-off to see if it gets stored in the database? Are there any artisan commands to use or would I need to setup a route?
No worries. Yeah, you can create a simple get route to saveRatings() and just hit it in the browser. However, since you plan on using it with CRON, you can create a command now and call it with artisan.
Dino thank you so much for your help, got it working mate! I'll have a go with the CRON but will post another question if I run into any trouble.
Every time I hit the browser, it stores the request each time (causing duplicates). Can I amend something on my controller so it only adds new entries and updates existing ones?
All good! Found the ::updateOrCreate that's resolved it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.