フッターコンテンツにスキップ
Iron Academy Logo
C#を学ぶ
C#を学ぶ

その他のカテゴリー

.NET Aspire で Linux 上に POST インサートエンドポイントを検証付きで追加する

[[academy-video-youtube({"vid": "oAMMHR8kKnw", "start_time": "0", "title": "Linuxで for .NET AspireにおけるPOST Insertエンドポイントのバリデーション付き追加", "creator": "Tim Corey", "length": "20m 31s"})]]

APIからデータを読み込むだけではストーリーの半分です。 最終的には、あらゆるアプリケーションが新しいレコードを受け入れる必要があり、それにはリクエストボディを受け取り、入力を検証し、データベースに永続化し、意味のあるステータスコードを返すPOSTエンドポイントを構築することを意味します。 プロトタイプの際に検証ステップをスキップすることは魅力的ですが、未検証の入力を受け入れるプロダクションAPIは、予防よりも修正しづらい破損したデータの原因となります。

Linux上 for .NET Aspireでの検証付きPOST挿入エンドポイントの追加という彼のビデオで、ティム・コーリーは、Tiny Ticket APIに挿入エンドポイントを追加し、専用の入力レコード型を作成し、最小API用 for .NETの組み込み検証パイプラインを接続し、APIが開始されると自動的に起動するようにSwaggerを設定します。 このエピソードは、ストアドプロシージャからテスト済みのエンドポイントに至る完全なサイクルをカバーし、.NETが自動的に返す検証エラーレスポンスのフォーマットを含みます。 Linux上のC#シリーズをフォローしている場合、または最小APIに書き込み操作を追加する初めての場合、この記事では各ステップを説明します。

挿入レコード型の作成

[1:46 - 4:43] エンドポイントを構築する前に、Timは挿入リクエストの形を表すデータ転送オブジェクトを作成します。既存のCreatedDateといったフィールドが含まれています。 POSTボディでそれらを受け入れると、無視されるか衝突を引き起こす可能性があるため、呼び出し元が提供すべきフィールドのみに入力をスコープするための別の型を設定しています。

public record TicketInsertRecord(string Title, string Description, int Priority);
public record TicketInsertRecord(string Title, string Description, int Priority);

classの代わりに使用するのは意図的な選択です。レコードはデフォルトで値ベースの等価性と不変性を提供し、リクエストペイロードのセマンティクスに適しています: データは到着し、バリデーションされ、データベースに渡され、途中で変更されることはありません。 3つのプロパティ(タイトル、説明、優先度)は、spTickets_Insertストアドプロシージャのパラメータに直接マップされます。

POSTエンドポイントのマッピング

[4:43 - 9:51] レコードタイプが定義されると、エンドポイント登録はGETルートと同じパターンに従いますが、MapPostを使用し、リクエストボディを挿入レコードにバインドします。

app.MapPost("/api/tickets", async (TicketInsertRecord ticket, IDbConnection db) =>
{
    await db.SaveDataAsync("spTickets_Insert", ticket);
    return Results.NoContent();
});
app.MapPost("/api/tickets", async (TicketInsertRecord ticket, IDbConnection db) =>
{
    await db.SaveDataAsync("spTickets_Insert", ticket);
    return Results.NoContent();
});

ルートはIDセグメントなしの/api/ticketsであり、コレクションURLにPOSTすることで新しいリソースを作成するREST規約に一致します。 ストアドプロシージャは、すべてのticketオブジェクトをパラメータバッグとして呼び出します。 Dapperは、レコードのプロパティを名前でSQLパラメータにマッピングします。

Results.NoContent()を返すと204ステータスコードが送信されます。 Timは理由を説明します:挿入は成功しましたが、応答本文に返す意味のあるものはありません。 一部のAPIは、新しく作成されたオブジェクトを201 CreatedステータスとLocationヘッダーで返し、新しいリソースへのポインターを示します。Tiny Ticketプロジェクトでは204を使用して効率的にしています。

Swaggerを通じたインサートのテスト

[9:51 - 14:43] Timはプロジェクトを立ち上げ、Swaggerに移動します。 POSTエンドポイントはTicketInsertRecordプロパティに一致するリクエストボディスキーマで表示されます。 彼はタイトル、説明、優先度を含むテストチケットを入力し、リクエストを実行します。

204が戻り、挿入が成功したことを確認します。 データが実際に保存されたことを確認するために、彼はすべてのエンドポイントを取得に切り替え、実行します。 新しいチケットが、元のテストレコードと共にリストに表示されます。

テストが明らかにするのは、検証がないことによるギャップです:空のタイトル、説明の欠如、優先度99の送信がすべて204で成功します。データベースはAPIが送信するものをすべて受け付けます。 そのギャップが次のセクションの動機となります。

組み込み検証の追加

[14:43 - 18:28] .NET 10以降では、最小APIは検証パイプラインをサポートしています。これにより、入力タイプからデータ注釈属性を読み込み、ハンドラーが実行される前に無効なリクエストを拒否します。 Timは、それを2ステップで組み込んでいます。

まず、Program.csでバリデーションサービスを登録してください。 この1行で、全体のパイプラインがアクティブ化されます。

builder.Services.AddValidation();
builder.Services.AddValidation();

サービスが登録されると、フレームワークはハンドラーが実行される前にすべてのリクエストボディを検証属性についてチェックします。 第二ステップは、各フィールドが満たすべきルールで挿入レコードを注釈付けすることです。

public record TicketInsertRecord(
    [Required, MinLength(1)] string Title,
    [Required] string Description,
    [Range(1, 5)] int Priority
);
public record TicketInsertRecord(
    [Required, MinLength(1)] string Title,
    [Required] string Description,
    [Range(1, 5)] int Priority
);

[Required]はフィールドが存在していることとnullでないことを保証します。 [MinLength(1)]は、空の文字列が必要なチェックを通過するのを防ぎます(空の文字列は技術的にはnullではありません)。 [Range(1, 5)]は優先度を有効な階層に制限します。 これらの属性は、ASP.NET MVCコントローラーが長年使用してきたSystem.ComponentModel.DataAnnotationsタイプと同じですが、追加のミドルウェアなしでミニマルAPIでも機能します。

保存して再起動した後、Timは空のタイトルと優先度を10にしてリクエストを送信します。応答は400 Bad Requestとして返され、構造化されたエラーボディが含まれています。

{
    "errors": {
        "Title": ["The Title field is required."],
        "Priority": ["The field Priority must be between 1 and 5."]
    }
}

検証パイプラインがリクエストを短絡し、無効なデータがデータベースに到達することはありません。 エラー応答はRFC 7807問題の詳細形式に従い、API消費者がプログラム的に解析できます。

起動時にSwaggerを自動起動する

[19:44 - 20:31] エピソードの締めくくりとして、小さな生活の質の改善が登場します。 TimがAPIを起動するたびに、手動で/swaggerをブラウザのURLに入力しなければなりませんでした。 その自動化のために、APIプロジェクトのlaunchUrlプロパティを追加します。

{
    "profiles": {
        "https": {
            "launchUrl": "swagger"
        }
    }
}

次の起動時には、ブラウザがデフォルトページではなく、Swagger UIに直接開きます。 これにより、デバッグサイクルごとに数秒が節約され、開発セッション全体で蓄積されます。

結論

[20:09 - 20:31] ミニマルAPIにPOSTエンドポイントを追加するには、専用の入力レコードを作成し、それをコレクションURLでMapPostにマッピングし、そのレコードをパラメータオブジェクトとしてストアドプロシージャを呼び出します。 .NET 10の検証には、1つのサービス登録とレコードプロパティに対する標準的なデータ注釈属性が必要です。 フレームワークは400応答のフォーマットを自動で処理します。

シリーズナビゲーション: この記事はC# on Linuxシリーズの一部で、Tiny Ticketアプリを構築しています。以前: IDで取得エンドポイントを追加。 次: PUT更新エンドポイントを追加

例のヒント: 挿入ストアドプロシージャが新しいレコードのIDを返す場合、Results.Created($"/api/tickets/{newId}", result)に戻りを変更し、呼び出し元が201ステータスで場所ヘッダーを取得できるようにし、それをフォローして作成されたリソースを取得できます。

彼のYouTubeチャンネルフルビデオを視聴し、C# on Linuxシリーズでの書込エンドポイント構築に関するさらなる洞察を得てください。

Hero Worlddot related to .NET Aspire で Linux 上に POST インサートエンドポイントを検証付きで追加する
Hero Affiliate related to .NET Aspire で Linux 上に POST インサートエンドポイントを検証付きで追加...

好きなことを共有することで収入を増やす

.NET、C#、Java、Python、またはNode.jsを使用する開発者向けのコンテンツを作成しますか?あなたの専門知識を副収入に変えましょう!

アイアンサポートチーム

私たちは週5日、24時間オンラインで対応しています。
チャット
メール
電話してね