Overview
このチュートリアルでは、簡単なタスクトリガー システムを構築して、LambdaアプリケーションでMongoDBを使用する方法を学習できます。アプリケーションでは、タスクを作成、読み取り、更新、および削除することができます。さらに、スケジュールされた時間に基づいて今後のタスクのリダイレクトをメールで送信します。
前提条件
このチュートリアルを開始する前に、開発環境に次のコンポーネントがインストールされていることを確認してください。
また、 MongoDB Atlasクラスターを設定する必要があります。クラスターのセットアップ方法を学ぶには、クイック スタートガイドを参照してください。
手順
MongoDB Lambdaパッケージをインストールします。
アプリケーションでMongoDBを使用するには、Lambda MongoDBパッケージをインストールし、それを config/database.phpファイルで構成する必要があります。
次のコマンドを使用してパッケージをインストールします。
composer require mongodb/laravel-mongodb
Tip
上記のコマンドを実行するとエラーが発生した場合は、 MongoDB PHP拡張機能がインストールされていることを確認してください。インストールする方法については、使用開始ガイドのMongoDB PHP拡張機能のインストールの手順を参照してください。
データベース接続を構成します。
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>
フォームには、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>
編集フォームには、作成フォームと同じ入力フィールドが含まれ、現在編集中のタスクのデータが読み込まれます。
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>
このビューには、作成フォームへのリンクが含まれており、すべてのタスクをループ処理して、認証されたユーザーに属するタスクを表示します。
タスクのナビゲーション リンクを追加しました。
アプリケーションナビゲーションからタスク機能へのリンクを追加します。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ジョブを構成する
次のステップ
このチュートリアルで説明されている概念をさらに学ぶには、次のリソースを参照してください。