はじめに
こんにちは、エンジニアのkeitaMaxです。
以前記事にしたアニメ一覧APIでアニメ情報を取得をする
の続きです。
今回はLaravel11を使用してAPIから2024年の春にやったアニメ一覧をDBに保存しようと思います。
テーブル作成
以下コマンドでマイグレーションファイルを作成します。
php artisan make:migration create_animations_table
中身は以下のようにしました。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('animations', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->softDeletes();
$table->text('title')->nullable();
$table->text('title_kana')->nullable();
$table->text('title_en')->nullable();
$table->text('media')->nullable();
$table->text('official_site_url')->nullable();
$table->text('wikipedia_url')->nullable();
$table->text('facebook_image_url')->nullable();
$table->integer('episodes_count')->nullable();
$table->text('season_name')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('animations');
}
};
これで以下コマンドでマイグレーションファイルを流し、テーブルを作成します。
コマンド作成
以下のコマンドでコマンドを作成します。
php artisan make:command GetThisTermAnimations
コマンドからAPIを叩いてDBに保存する処理を作成
以下のコマンドでコマンドを作成します。
php artisan make:command GetThisTermAnimations
コマンドでAPIを叩く処理を作成
以下のように作成しました。
GetThisTermAnimations.php
<?php
namespace App\Console\Commands;
use App\Models\Animation;
use Illuminate\Console\Command;
class GetThisTermAnimations extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:get-this-term-animations';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle($page = 1)
{
$terms = $this->argument('term');
$termId = $this->argument('termId');
$url = "https://api.annict.com/v1/works?filter_season=2024-spring&page=$page";
$ch = curl_init();
$apiKey = config('app.annict_api_key');
$headers = [
'Authorization: Bearer ' . $apiKey,
'Accept: application/json',
];
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$error = curl_error($ch);
if ($error) {
$this->info("error $error");
return;
}
curl_close($ch);
$responseArray = json_decode($response);
foreach ($responseArray->works as $animation) {
Animation::firstOrCreate([
"title" => $animation->title,
"title_kana" => $animation->title_kana,
"title_en" => $animation->title_en,
"media" => $animation->media,
"official_site_url" => $animation->official_site_url,
"wikipedia_url" => $animation->wikipedia_url,
"facebook_image_url" => $animation->images->facebook->og_image_url,
"episodes_count" => $animation->episodes_count,
"season_name" => $animation->season_name,
]);
}
if ($responseArray->next_page) {
$this->handle($responseArray->next_page);
}
}
}
1回APIを叩くと、最大25までしか取得ができないので、
if ($responseArray->next_page) {
sleep(1);
$this->handle($responseArray->next_page);
}
このように次のページがあった場合にもう一度APIを叩くようにしています。
また、sleep(1);
によって連続で叩かないようにしています。
また、config
にAPIKeyを設定し、envファイルにキーを置いています。
実行
以下コマンドで実行します。
php artisan app:get-this-term-animations
これを実行し、DBを見ると実際にアニメの一覧が入っていることがわかります。
おわりに
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!
参考