Overview
このチュートリアルでは、簡単なタスクトリガー システムを構築して、LambdaアプリケーションでMongoDBを使用する方法を学習できます。アプリケーションでは、タスクを作成、読み取り、更新、および削除することができます。さらに、スケジュールされた時間に基づいて今後のタスクのリダイレクトをメールで送信します。
前提条件
このチュートリアルを開始する前に、開発環境に次のコンポーネントがインストールされていることを確認してください。
また、 MongoDB Atlasクラスターを設定する必要があります。クラスターのセットアップ方法を学ぶには、クイック スタートガイドを参照してください。
手順
MongoDB Lambdaパッケージをインストールします。
アプリケーションでMongoDBを使用するには、Lambda MongoDBパッケージをインストールし、それを config/database.phpファイルで構成する必要があります。
次のコマンドを使用してパッケージをインストールします。
composer require mongodb/laravel-mongodb
Tip
If you encounter an error when you run the preceding command, ensure that the MongoDB PHP extension is installed. To learn how to install, see the Install the MongoDB PHP extension step in the Get Started guide.
データベース接続を構成します。
Lambda MongoDBパッケージのインストールが完了したら、config/database.phpファイルにMongoDBデータベース接続を追加して構成を完了します。次のMongoDB構成を、他のデータベースタイプの構成を含む connections 配列に追加します。
return [ 'connections' => [ 'mongodb' => [ 'driver' => 'mongodb', 'dsn' => env('MONGODB_URI'), 'database' => 'task_reminder', ], // Other connections here ], ];
アプリケーションは.envファイルから dsn 値を取得します。.envファイルに移動します。次に、MONGODB_URI の値を作成し、それをMongoDB接続文字列の値に設定します。
Tip
MongoDB接続文字列を取得するには、 MongoDB Atlasのクラスターに移動します。[Connect ボタンをクリックし、Connect your application の下の Drivers をクリックします。Driver 選択メニューから [PHP] を選択します。ダイアログ ボックスから接続文字列をコピーします。接続文字列を取得する方法の詳細については、接続文字列の作成 を参照してください。
.envファイルで、DB_CONNECTION の値を mongodb に設定して、アプリケーションのデフォルト接続とします。次のコードに示すように、SESSION_DRIVER の値を編集し、mongodb に設定します。
MONGODB_URI=mongodb+srv://YOUR_MONGODB_CONNECTION_STRING DB_CONNECTION=mongodb // Other DB_ values here ... SESSION_DRIVER=mongodb
Lambda で認証を設定する
アプリケーションをインストールしてMongoDBで動作するように構成したら、認証を設定します。Lambda は、Lalavel Releases、Lalavel Fortify、Lambel jetstream などのパッケージを提供することで認証実装を簡素化します。このチュートリアルでは、認証に Laravel Breeze を使用します。
Composer を使用して Lambda をインストールします。
composer require laravel/breeze --dev
インストールが完了したら、次のコマンドを実行します。
php artisan key:generate php artisan breeze:install php artisan migrate php artisan db:seed npm install npm run dev
希望するスタックとテストパッケージを選択するよう求められます。このチュートリアルでは、最初のオプションである [Blain with Alplica ] を選択します。
┌ Which Breeze stack would you like to install? ───────────────┐ │ > ● Blade with Alpine │ │ ○ Livewire (Volt Class API) with Alpine │ │ ○ Livewire (Volt Functional API) with Alpine │ │ ○ React with Inertia │ │ ○ Vue with Inertia │ │ ○ API only │ └──────────────────────────────────────────────────────────────┘
このコマンドは、認証ビュー、ルート、コントローラー、およびその他の関連リソースをアプリケーションに追加します。
MongoDBのユーザー モデルと認証を構成します。
Lambda はSQLデータベース用のデフォルトのユーザーモデルを作成します。MongoDBで動作し、レート制限の互換性の問題を解決するには、これを更新する必要があります。
app/Models/User.php を開き、その内容を次のように置き換えます。
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Notifications\Notifiable; use MongoDB\Laravel\Auth\User as MongoUser; class User extends MongoUser { use HasFactory, Notifiable; protected $connection = 'mongodb'; protected $collection = 'users'; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * Get the attributes to cast. * * @return array<string, string> */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } }
プロジェクトを提供し、 MongoDB接続をテストします。
Lambda の組み込みサーバーを使用してプロジェクトを処理し、すべてが正常に動作することを確認します。Lambdaプロジェクトディレクトリで、次のコマンドを実行します。
php artisan serve
このプロジェクトは127.0.0.1:8000 で提供されています。ポート 8000 がすでに使用されている場合、Lambel は新しく使用可能なポートに切り替え、ターミナルに出力します。
認証システムをテストするには、アプリケーションで [Register] ボタンを選択し、新しいユーザー アカウントを作成します。これにより、ユーザーがMongoDBデータベースに保存され、それらの認証情報でログできるようになります。このチュートリアルでは、ユーザー名をtest@example.com に、パスワードを password に設定できます。
Lambda MongoDBパッケージが正しく構成されていることを確認するには、 MongoDBクラスターにpingためのルートを作成します。以下を routes/web.php に追加します。
Route::get('/ping', function (Request $request) { $connection = DB::connection('mongodb'); try { $connection->command(['ping' => 1]); $msg = 'MongoDB is accessible!'; } catch (\MongoDB\Driver\Exception\ConnectionException $e) { $msg = 'You are not connected to MongoDB. Error: ' . $e->getMessage(); } return ['msg' => $msg]; });
ブラウザでこのルートにアクセスしてください。正しい構成では、「MongoDBがアクセス可能です。」というメッセージが表示されます。ブラウザに表示されます。
タスクモデルとコントローラーを作成します。
次のコマンドを使用して、タスク予定機能のモデルとコントローラーを作成します。
php artisan make:model Task --resource --controller
このコマンドは、リソースメソッドを使用して、app/Modelsディレクトリに Task モデルを作成し、app/Http/Controllersディレクトリに TaskController モデルを作成します。
routes/web.php に移動し、次のコードを追加して、TaskController のルートを作成します。
use App\Http\Controllers\TaskController; // Other route definitions... Route::resource('tasks', TaskController::class)->middleware('auth');
タスク モデルを構成します。
app/Models/Task.php に移動し、ファイルの内容を次のコードで置き換えます。
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Task extends Model { protected $connection = 'mongodb'; protected $table = 'tasks'; protected $fillable = [ 'title', 'description', 'due_date', 'email', 'reminder_time', 'last_notification_date' ]; }
このコードは、次の仕様でタスクモデルを作成します。
名前空間の後の
use MongoDB\Laravel\Eloquent\ModelステートメントはMongoDBモデルに固有です。MongoDBクエリを使用することで、 SQLで実装された Elastic 機能を上書きします。protected $table = 'tasks'プロパティは任意です。このモデルからのドキュメントを保存するために使用されるMongoDBコレクションの名前を指定します。protected $fillableプロパティは、一括割り当て可能なプロパティを指定します。
Tip
MongoDBのユニークな機能の 1 つは、関係データベースのような移行が必要ないことです。モデルを更新したり移行を作成したりすることなく、ドキュメントに新しいフィールドを直接追加できます。この機能は、動的データを処理するのに便利です。
TaskCluster ロジックを作成します。
app/Http/Controllers/TaskController.php に移動し、次のコードでコンテンツを更新します。
namespace App\Http\Controllers; use App\Models\Task; use Carbon\Carbon; use Illuminate\Http\Request; class TaskController extends Controller { /** * Displays a listing of the resource. */ public function index() { $tasks = Task::where('email', auth()->user()->email)->get(); return view('tasks.index', compact('tasks')); } /** * Shows the form for creating a new resource. */ public function create() { return view('tasks.create'); } /** * Stores a newly created resource in storage. */ public function store(Request $request) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'due_date' => 'required|date', 'reminder_time' => 'required|date', ]); $data['due_date'] = Carbon::parse($request->due_date); $data['reminder_time'] = Carbon::parse($request->reminder_time); $data['email'] = auth()->user()->email; $data['last_notification_date'] = null; Task::create($data); return redirect()->route('tasks.index')->with('success', 'Task created successfully.'); } /** * Displays the specified resource. */ public function show(string $id) { // } /** * Shows the form for editing the specified resource. */ public function edit(string $id) { $tasks = Task::where('id', $id)->get(); return view('tasks.edit', ['tasks' => $tasks]); } /** * Updates the specified resource in storage. */ public function update(Request $request, string $id) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'due_date' => 'required|date', 'reminder_time' => 'required|date', ]); $task = Task::findOrFail($id); $data['due_date'] = Carbon::parse($request->due_date)->format('Y-m-d H:i:s'); $data['reminder_time'] = Carbon::parse($request->reminder_time)->format('Y-m-d H:i:s'); $task->update($data); return redirect()->route('tasks.index')->with('success', 'Task updated successfully.'); } /** * Removes the specified resource from storage. */ public function destroy(string $id) { $task = Task::findOrFail($id); $task->delete(); return redirect()->route('tasks.index')->with('success', 'Task deleted successfully.'); } }
TaskControllerクラスには、タスクモデルのCRUD操作を取り扱うコードが含まれています。
index()メソッドは、ログイン ユーザーに属するすべてのタスクを取得し、それをindex.blade.phpファイルに送信して表示します。create()メソッドは、 新しいタスクを作成するためのフォームビューを返します。store()メソッドは入力を検証し、ログイン ユーザーのメールをタスクに割り当て、それをデータベースに保存します。edit()メソッドは、編集する特定のタスクを取得し、編集フォームに表示します。update()メソッドは編集したタスクをMongoDBタスクコレクションに保存します。destroy()メソッドは特定のタスクを削除します。
各操作は、 ユーザーフィードバックの成功メッセージとともにタスクリストにリダイレクトされます。
タスクスケジューラーのビュー ファイルを作成します。
resources/viewsディレクトリに、tasks という名前のフォルダーを作成し、その中に次のファイルを作成します。
create.blade.phpedit.blade.phpindex.blade.php
resources/views/tasks/create.blade.php に移動し、次のコンテンツを追加します。
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Tasks') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="container mx-auto p-4"> 12 <h2 class="text-2xl font-bold mb-4">Create New Task</h2> 13 14 <form action="{{ route('tasks.store') }}" method="POST"> 15 @csrf 16 17 <div class="mb-4"> 18 <label for="title" class="block text-gray-700">Title:</label> 19 <input type="text" 20 name="title" 21 id="title" 22 required 23 class="border border-gray-300 p-2 w-full" 24 value="{{ old('title') }}"> 25 @error('title') 26 <p class="text-red-500">{{ $message }}</p> 27 @enderror 28 </div> 29 30 <div class="mb-4"> 31 <label for="description" class="block text-gray-700">Description:</label> 32 <textarea name="description" 33 id="description" 34 class="border border-gray-300 p-2 w-full">{{ old('description') }}</textarea> 35 </div> 36 37 <div class="mb-4"> 38 <label for="due_date" class="block text-gray-700">Due Date:</label> 39 <input type="date" 40 name="due_date" 41 id="due_date" 42 required 43 class="border border-gray-300 p-2 w-full" 44 value="{{ old('due_date') }}"> 45 @error('due_date') 46 <p class="text-red-500">{{ $message }}</p> 47 @enderror 48 </div> 49 50 <div class="mb-4"> 51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label> 52 <input type="datetime-local" 53 name="reminder_time" 54 id="reminder_time" 55 class="border border-gray-300 p-2 w-full" 56 value="{{ old('reminder_time') }}"> 57 </div> 58 59 <button type="submit" 60 class="bg-green-600 text-white p-2 border rounded"> 61 Create Task 62 </button> 63 </form> 64 </div> 65 </div> 66 </div> 67 </div> 68 </x-app-layout> 69
フォームには、title と description のテキスト入力と、due date と reminder time の日付と時刻の入力が含まれています。
resources/views/tasks/edit.blade.php に移動し、次のコンテンツを追加します。
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Edit Task') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="p-6 text-gray-900"> 12 @foreach($tasks as $task) 13 <form action="{{ route('tasks.update', $task->id) }}" method="POST"> 14 @csrf 15 @method('PUT') 16 17 <div class="mb-4"> 18 <label for="title" class="block text-gray-700">Title:</label> 19 <input type="text" 20 name="title" 21 id="title" 22 required 23 class="border border-gray-300 p-2 w-full" 24 value="{{ old('title', $task->title) }}"> 25 @error('title') 26 <p class="text-red-500">{{ $message }}</p> 27 @enderror 28 </div> 29 30 <div class="mb-4"> 31 <label for="description" class="block text-gray-700">Description:</label> 32 <textarea name="description" 33 id="description" 34 class="border border-gray-300 p-2 w-full">{{ old('description', $task->description) }}</textarea> 35 </div> 36 37 <div class="mb-4"> 38 <label for="due_date" class="block text-gray-700">Due Date:</label> 39 <input type="date" 40 name="due_date" 41 id="due_date" 42 required 43 class="border border-gray-300 p-2 w-full" 44 value="{{ old('due_date', $task->due_date) }}"> 45 @error('due_date') 46 <p class="text-red-500">{{ $message }}</p> 47 @enderror 48 </div> 49 50 <div class="mb-4"> 51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label> 52 <input type="datetime-local" 53 name="reminder_time" 54 id="reminder_time" 55 class="border border-gray-300 p-2 w-full" 56 value="{{ old('reminder_time', $task->reminder_time) }}"> 57 </div> 58 59 <button type="submit" 60 class="bg-blue-500 text-white p-2 rounded"> 61 Update Task 62 </button> 63 </form> 64 @endforeach 65 </div> 66 </div> 67 </div> 68 </div> 69 </x-app-layout> 70
編集フォームには、作成フォームと同じ入力フィールドが含まれ、現在編集中のタスクのデータが読み込まれます。
resources/views/tasks/index.blade.php に移動し、次のコンテンツを追加します。
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Tasks') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="p-6 text-gray-900"> 12 <div class="mb-2"> 13 <a href="{{ route('tasks.create') }}" 14 class="p-2 border mb-4"> 15 Create New Task 16 </a> 17 </div> 18 19 <ul class="mt-4"> 20 @foreach ($tasks as $task) 21 <div class="mt-2"> 22 <hr> 23 </div> 24 25 <li> 26 <h1 class="text-2xl"> 27 <strong>{{ $task->title }}</strong> 28 - Due: {{ $task->due_date }} 29 </h1> 30 31 <p class="text-gray-600"> 32 {{ $task->description }} 33 </p> 34 35 <div class="flex gap-2 mt-4"> 36 <div class="p-2 text-white bg-gray-700"> 37 <a href="{{ route('tasks.edit', $task->id) }}"> 38 Edit 39 </a> 40 </div> 41 42 <div class="p-2 text-white bg-red-700 rounded"> 43 <form action="{{ route('tasks.destroy', $task->id) }}" 44 method="POST" 45 style="display:inline;"> 46 @csrf 47 @method('DELETE') 48 <button type="submit">Delete</button> 49 </form> 50 </div> 51 </div> 52 </li> 53 @endforeach 54 </ul> 55 </div> 56 </div> 57 </div> 58 </div> 59 </x-app-layout> 60
このビューには、作成フォームへのリンクが含まれており、すべてのタスクをループ処理して、認証されたユーザーに属するタスクを表示します。
タスクのナビゲーション リンクを追加しました。
アプリケーションナビゲーションからタスク機能へのリンクを追加します。resources/views/layouts/navigation.blade.php にGo、ダッシュボード ナビゲーション リンクの後に次のコードを追加します。
1 // ...existing code ... 2 <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex"> 3 <x-nav-link :href="route('tasks.index')" :active="request()->routeIs('tasks.index')"> 4 {{ __('Tasks') }} 5 </x-nav-link> 6 </div>
この点で、タスクマネジメントシステムのCRUD操作をテストできます。次のセクションに入る前に、すべてが正しく動作していることを確認してください。
トリガーを送信するためのカスタム アーティファクト コマンドを作成します。
期限が切れたタスクのトリガー システムを実装するには、メールでトリガーを送信するためのカスタム アーティアン コマンドを作成し、コマンドを自動スケジュール用に登録します。
カスタム アーティザ コマンドを作成するには、ターミナルで次のコードを実行します。
php artisan make:command SendTaskReminders
コマンドを作成した後、次のコードで app/Console/Commands/SendTaskReminders.phpファイルの内容を更新します。
namespace App\Console\Commands; use App\Models\Task; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Support\Facades\Mail; class SendTaskReminders extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'app:send-task-reminders'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Execute the console command. */ public function handle() { $now = Carbon::now(); $upcomingTasks = Task::where('last_notification_date', null)->get(); $upcomingTasks = Task::where('last_notification_date', null) ->where('reminder_time', '>=', $now->clone()->subMinutes(10)) ->get(); foreach ($upcomingTasks as $task) { $emailBody = <<<EOF Hello, This is a reminder for your task: Title: {$task->title} Description: {$task->description} Due Date: {$task->due_date} Please make sure to complete it on time! Regards, Your Task Reminder App EOF; Mail::raw($emailBody, function ($message) use ($task) { $message->to($task->email) ->subject("Task Reminder: {$task->title}"); }); $task->last_notification_date = $now; $task->save(); $this->info("Reminder email sent for task: {$task->title}"); } return self::SUCCESS; } }
カスタム アーティファクト コマンドのメイン ロジックは handle() メソッドに記述されています。このコードは Carbon::now() を使用して現在のタイムスタンプを取得します。
次に、データベースをクエリして、reminder_time が現在の時刻以下、かつ reminder_time が現在の時刻の 10 分以上であるすべてのタスクを取得します。MongoDBでは、すべての日付は UTC で保存されます。サーバーが別の タイムゾーンを使用している場合でも、 タイムゾーンを変更する必要はありません。
クエリは、次の 10 分に期限されるすべてのタスクを取得します。このコードは結果をループ処理し、次の 10 分に期限が切れるタスクのユーザーのメールにリマインダーを送信します。
注意
タスクタスクが正しく動作するには、アプリケーションがメールを送信するように構成する必要があります。Emailtap.io は、メールの送信をテストするのに便利なツールです。Laravelでメールを送信するについて学ぶには、こちらをご覧ください。
タスクトリガーの通知をスケジュールします。
設定を完了するには、前のステップで作成された Artisan コマンドを 1 分ごとに実行するように予定します。このアプローチでは、1 分ごとに php artisan app:send-task-reminders が自動的に実行されます。
routes/console.php に移動し、次のコードを追加します。
// ...existing code ... Schedule::command('app:send-task-reminders')->everyMinute();
これが動作するかどうかをテストするには、次のコマンドを実行します。
php artisan schedule:run
本番環境サーバーでは、php artisan schedule:run コマンドを定期的に実行するように cronジョブを構成する必要があります。
Linuxまたは Unix ベースのサーバーでは、次のコマンドを使用して cron構成ファイルを開くことができます。
crontab -e
次のコードを cron 構成タブに追加します。
* * * * * /usr/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
/usr/bin/php をPHPバイナリへのパスに置き換え、/path-to-your-project をサーバー上の Lambdaプロジェクトへの完全なパスに置き換えます。ファイルを保存して終了します。
cronジョブが正しく設定されていることを確認するには、次のコマンドを実行します。
crontab -l
概要
これで、 Lambda とMongoDBを使用するタスクスケジューラーアプリケーションができました。このチュートリアルでは、次のアクションを完了する方法について説明します。
MongoDBと連携するために Lambdaプロジェクトを構成する
タスクスケジューラーのCRUD機能を実装する
トリガー システム用のカスタム Lambda アーティサンド コマンドを作成する
タスクをスケジュールしてアーティザ コマンドを間隔ごとに実行する
Linux ベースのサーバーで cronジョブを構成する
次のステップ
このチュートリアルで説明されている概念をさらに学ぶには、次のリソースを参照してください。
使用例 一般的な操作のコード例について
Eloquentモデルを操作するためのEloquent Modelクラス