本記事では、JavaScriptとWeb APIを用いてデータベースのCRUD処理を行う方法を、2025年1月時点における最新の技術と弊社製品とともにご紹介します。
2022年に公開した過去の記事はこちらです。
本記事では以下の環境+技術を使用します。
- ASP.NET Core Web API(Minimal API)
- Azure SQL Database
- Entity Framework Core
- Visual Studio 2022 + .NET 9
- Visual Studio Code
- Vite
目次
サーバーサイド(データベース)
サーバーサイドのWeb APIはデータベースのCRUD処理を実装します。クライアントサイドとサーバーサイド間のデータの受け渡しにはJSONを使用します。
Azure SQL Databaseの作成
AzureポータルからSQL Databaseを追加しておきます。サーバー名をmesciustestdbsrv2025、データベース名をAdventureWorksとして作成し、作成時の「追加設定」の項目から、Azureに用意されている「AdventureWorksLT」のサンプルを指定して使用します。

また、「サーバーファイアウォールの設定」から、「クライアントIPv4アドレス」にローカルのIPアドレスを追加し、実行するクライアント環境からアクセスできるようにしておきます。

サーバーサイド(Web API)
Visual Studio 2022でASP.NET Core Web APIアプリケーションを作成します。プロジェクトテンプレートから「ASP.NET Core Web API」を選択します。

プロジェクト名にはCRUDWebApiAppを設定しています。

「追加情報」でフレームワークに「 .NET 9」を指定し、「Open APIサポートを有効にする」にチェックを入れ、さらに「コントローラーを使用する」のチェックを外し、Minimal APIを使用してAPIを構築していきます。

モデルの作成(リバースエンジニアリング)
今回はデータベースファーストでAzure SQL DatabaseのAdventureWorksからモデルをリバースエンジニアリングします。CLIから実行することもできますが、Visual Studioのマーケットプレイスで公開されている「EF Core Power Tools」を使ってGUIから実行してみます。
ダウンロードしたVSIXファイルを実行し、インストールするVisual Studioを指定してインストールします。


インストール完了後、Visual Studioでプロジェクトを右クリックし、「追加」⇒「新しい項目」を選択し、「新しい項目の追加」ダイアログを開くと、「Data」の項目で「EF Core Database First Wizard」が選択可能になっているので、これを追加します。

以下のようなダイアログが立ち上がるので、[追加]⇒「データベース接続追加」を選択します。

次のダイアログでデータベースの接続情報を入力します。正常に接続されたら「データベースの選択または入力」の項目で「AdventureWorks」が選択できるようになっているので、これを選択して[OK]を押下します。

新しく追加したデータ接続定義を選択し、加えてEF Coreのバージョンを選択したら[OK]を押下します。

追加するデータベースオブジェクトを選択して[OK]を押下します。

次のダイアログでコンテキスト名などプロジェクトの設定を変更できます。今回はデフォルトの設定のまま[OK]を押下します。

ツールによりリバースエンジニアリングが実行され、以下のようにModelsフォルダに各テーブル用のモデルが作成されます。

接続文字列とクロスオリジンリクエスト(CORS)の設定
次にデータベースの接続文字列の設定をappsettings.jsonに追加します。
{
  ・・・(中略)
  "ConnectionStrings": {
    "Connection": "作成したAzure SQL Databaseの接続文字列"
  }
}Program.csにappsettings.jsonから接続文字列を使用するコードを追加します。
using CRUDWebApiApp.Models;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
builder.Services.AddDbContext<AdventureWorksContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("Connection"));
});
・・・(中略)次にクライアントサイドからWeb APIを利用するためにCORSを有効にしておきます。以下のコードをProgram.csに追加します。
using CRUDWebApiApp.Models;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
var MyAllowOrigins = "_myAllowOrigins";
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowOrigins,
                      builder =>
                      {
                          builder.AllowAnyOrigin()
                                 .AllowAnyMethod()
                                 .AllowAnyHeader();
                      });
});
・・・(中略)
app.UseHttpsRedirection();
app.UseCors(MyAllowOrigins);
・・・(中略)スキャフォールドの実行
次に先ほど作成したモデルからCRUD処理を行うAPIをスキャフォールドしていきます。
ソリューションエクスプローラーでプロジェクトを右クリックし、「追加」⇒「新規スキャフォールディングアイテム」を選択すると、「新規スキャフォールディングアイテムの追加」ダイアログが開くので、「Entity Frameworkを使用した、読み取り/書き込みエンドポイントを含むAPI」を選択し、[追加]を押下します。

「モデルクラス」と「エンドポイントクラス」にCustomer、「DbContextクラス」にAdventureWorksContextを設定し、[追加]を押下します。

完了するとCustomer.csに以下のようなAPIのCRUD処理の定義が追加されます。

また、Program.csに上記の処理の呼び出しが自動的に追加されます。

Customer.csの中でスキャフォールドしたCRUD処理では、パスパラメータの名称と受け取る側のパラメータの名称が合っていないので、手動で修正(customerid⇒id)します。また、PUT時にIDENTITY列のCustomerIdを更新しないようにコードを削除するのと、POST時にGUIDと更新日付の項目の値をプログラムで設定するように処理を追加します。
・・・(中略)・・・
public static class CustomerEndpoints
{
	public static void MapCustomerEndpoints (this IEndpointRouteBuilder routes)
    {
・・・(中略)・・・
        group.MapGet("/{id}", async Task<Results<Ok<Customer>, NotFound>> (int id, AdventureWorksContext db) =>
        {
            return await db.Customers.AsNoTracking()
                .FirstOrDefaultAsync(model => model.CustomerId == id)
                is Customer model
                    ? TypedResults.Ok(model)
                    : TypedResults.NotFound();
        })
        .WithName("GetCustomerById")
        .WithOpenApi();
        group.MapPut("/{id}", async Task<Results<Ok, NotFound>> (int id, Customer customer, AdventureWorksContext db) =>
        {
            var affected = await db.Customers
                .Where(model => model.CustomerId == id)
                .ExecuteUpdateAsync(setters => setters
//                  .SetProperty(m => m.CustomerId, customer.CustomerId)
                  .SetProperty(m => m.NameStyle, customer.NameStyle)
・・・(中略)・・・
        group.MapPost("/", async (Customer customer, AdventureWorksContext db) =>
        {
            customer.Rowguid = Guid.NewGuid();
            customer.ModifiedDate = DateTime.Now;
            db.Customers.Add(customer);
            await db.SaveChangesAsync();
            return TypedResults.Created($"/api/Customer/{customer.CustomerId}",customer);
        })
・・・(中略)・・・
        group.MapDelete("/{id}", async Task<Results<Ok, NotFound>> (int id, AdventureWorksContext db) =>
        {
            var affected = await db.Customers
                .Where(model => model.CustomerId == id)
・・・(中略)・・・
}APIドキュメントの生成
.NET 9よりSwagger UIが自動で作成されなくなり、OpenAPIのJSONドキュメントのみの提供となったので、「Scalar」を使ってAPIドキュメントを生成します。
プロジェクトを右クリック⇒「NuGetパッケージの管理」から、「Scalar.AspNetCore」のパッケージをインストールします。

次にProgram.csを以下のように追記します。
・・・(中略)・・・
using Scalar.AspNetCore;
・・・(中略)・・・
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
    app.MapScalarApiReference();
};
・・・(中略)・・・Web APIの実行
以上でWeb APIの設定は完了です。ここで一度APIを実行したいと思いますが、その前にProgram.csから以下のハイライト部分を削除し、デフォルトのWeatherForecastのAPIを削除しておきます。
・・・(中略)・・・
var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast");
・・・(中略)・・・
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}アプリケーションを実行し、「Web APIのURL/scalar/v1」にアクセスすると、自動生成されたAPIドキュメントが表示され、ここからAPIのテスト等も実行できます。

クライアントサイド
クライアントサイドはVisual Studio Codeを使用してJavaScriptとHTMLで開発します。データの表示と操作には「Wijmo(ウィジモ)」のFlexGrid(データグリッドコントロール)とCollectionView(変更データを管理するためのユーティリティクラス)を使用します。
プロジェクトを作成する
まず、ターミナルで以下のコマンドを実行し、Viteを使ってWijmoFlexGridプロジェクトを作成します。
npm create vite@latest WijmoFlexGrid -- --template vanilla以下のコマンドを順に実行し、必要なパッケージをインストールします。
cd WijmoFlexGrid
npm install続けて以下のコマンドを実行してアプリケーションを起動し、「http://localhost:5173/」にアクセスすると、ベースとなるJavaScriptのアプリケーションを確認できます。
npm run dev
WijmoのFlexGridとCollectionViewを使う
次にnpmでWijmoをインストールします。
npm install @mescius/wijmo.purejs.allindex.htmlファイルを以下のように書き換え、FlexGridを表示するためのdiv要素を追加します。
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>
      Wijmo FlexGridサンプル
  </title>
  <script type="module" src="/src/main.js"></script>
</head>
<body>
  <div class="container">
      <button id="update">更新</button>
      <div id="flexGrid" style="height: 600px;"></div>
  </div>
</body>
</html>src/main.jsに下記のコードを追加します。CollectionViewとFlexGridを生成します。
※ ライセンスキーを設定しない場合トライアル版を示すメッセージが表示されます。ライセンスキーの入手や設定方法についてはこちらをご覧ください。
import './style.css'
import '@mescius/wijmo.styles/wijmo.css';
import '@mescius/wijmo.cultures/wijmo.culture.ja';
import * as wjGrid from '@mescius/wijmo.grid';
import * as wjCore from '@mescius//wijmo';
wjCore.setLicenseKey('ここにWijmoのライセンスキーを設定します');
let cv = new wjCore.CollectionView();
cv.trackChanges = true;
let flexGrid = new wjGrid.FlexGrid('#flexGrid', {
    itemsSource: cv,
    allowAddNew: true,
    allowDelete: true
});src/style.cssを以下のように書き換えます。
body{
  margin: 10px;
}この時点で一度実行してみます。Visual Studio Codeのターミナルで以下のコマンドを実行します
npm run dev「http://localhost:5173/」にアクセスすると、空のFlexGridと[更新]ボタンが表示されます。

CRUD処理を作成する
最後の仕上げとしてCRUD処理を実装していきます。
データの読み込み(READ)を行う
以下のコードをsrc/main.jshttprequestメソッドを使用します。
・・・(中略)・・・
let url = 'https://Web APIのURL/api/Customer/';
//GET
wjCore.httpRequest(url, {
  success: function (xhr) {
    cv.sourceCollection = JSON.parse(xhr.response);
  }
});再度実行すると、データベースから読み込んだデータがFlexGridに表示されます。

データの更新(UPDATE)を行う
以下のコードをsrc/main.jsに追加します。更新されたデータの一覧(CollectionView.itemsEditedプロパティ)を取得してWeb APIにPUTリクエストを送信します。PUTリクエストではURLに更新データのID「cv.itemsEdited[i].customerId」を指定して、dataに更新データ「cv.itemsEdited[i]」を指定します。
document.getElementById('update').addEventListener('click', function () {
    //PUT  
    for (var i = 0; i < cv.itemsEdited.length; i++) {
        wjCore.httpRequest(url + cv.itemsEdited[i].customerId, {
            method: 'PUT',
            data: cv.itemsEdited[i]
        });
    }
});再度実行し、FlexGrid上のデータを更新してから[更新]ボタンを押下し、ページをリロードするとデータベースに更新が反映されていることが確認できます(複数のデータを一度に更新することもできます)。
データの生成(CREATE)を行う
以下のコードをsrc/main.jsに追加します。追加されたデータの一覧(CollectionView.itemsAddedプロパティ)を取得して、Web APIにPOSTリクエストを送信します。POSTリクエストではdataに追加データ「cv.itemsAdded[i]」を指定します。
document.getElementById('update').addEventListener('click', function () {
・・・(中略)
    //POST
    for (var i = 0; i < cv.itemsAdded.length; i++) {
        wjCore.httpRequest(url, {
            method: 'POST',
            data: cv.itemsAdded[i]
        });
    }
});再度実行し、FlexGridの一番下にある空行のセルに適当なデータを入力し、[更新]ボタンを押下します(複数のデータを一度に追加することもできます)。ページをリロードすると、データベースのデータが追加されていることが確認できます。
データの削除(DELETE)を行う
以下のコードをsrc/main.jsに追加します。削除されたデータの一覧(CollectionView.itemsRemovedプロパティ)を取得して、Web APIにDELETEリクエストを送信します。DELETEリクエストでは、URLに削除データのID「cv.itemsRemoved[i].customerId」を指定します。
document.getElementById('update').addEventListener('click', function () {
・・・(中略)
    //DELETE
    for (var i = 0; i < cv.itemsRemoved.length; i++) {
        wjCore.httpRequest(url + cv.itemsRemoved[i].customerId, {
            method: 'DELETE'
        });
    }
});再度実行し、「データの生成(CREATE)」で追加したデータを削除してから[更新]ボタンを押下します。ページをリロードすると、データベースのデータが削除されていることが確認できます。
さいごに
以上がJavaScriptとWeb APIを用いたWebアプリケーションで、データベースのCRUD処理を実行する方法でした。今回クライアントサイドのアプリケーションで使用したWijmoを使用すると、HTTPリクエストの実行や、更新時に必要な変更箇所の追跡なども簡単に実行することができます。
製品サイトでは、Wijmoの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。
また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。
