.NET CoreでAPIを構築し、PostgreSQLをデータベースとして使用する方法
イントロダクション
この記事では、.NET CoreとPostgreSQLを使用してAPIを開発する方法について説明します。APIの開発には、DapperというORMツールを使用します。
Dapperは、シンプルで高速な.NETオブジェクトマッパーであり、SQLクエリの実行と結果のマッピングを容易に行うことができます。そのため、データベースとの対話を効率的に行うための強力なツールとして利用されています。
この記事では、.NET Coreのフレームワークを使用してAPIを構築し、PostgreSQLデータベースとの通信を行う方法に焦点を当てます。
開発環境
オペレーティングシステム: Windows 11 Home
開発ツール: Visual Studio 2022
データベース: PostgreSQL 16.3 (SQL Server 2022)
作成物の概要
ユーザー管理 API
このAPIは、ユーザーの作成、取得、更新、削除などの基本的な操作を提供します。
エンドポイント
- GET /api/users
- 全てのユーザーを取得します。
- GET /api/users/{id}
- 指定したIDのユーザーを取得します。
- POST /api/users
- 新しいユーザーを追加します。
- DELETE /api/users/{id}
- 指定したIDのユーザーを削除します。
- PUT /api/users/{id}
- 指定したIDのユーザー情報を更新します。
データモデル
ユーザーは以下のプロパティを持ちます。
-
Id
(int): ユーザーの一意の識別子。 -
Name
(string): ユーザーの名前。 -
Email
(string): ユーザーのメールアドレス。 -
Age
(int): ユーザーの年齢。
使用方法
- APIエンドポイントにリクエストを送信します。
- レスポンスを受け取ります。
- 必要に応じてレスポンスを処理します。
使用例
全てのユーザーを取得する
GET /api/users/1
指定したIDのユーザーを取得する
GET /api/users/1
新しいユーザーを追加する
POST /api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"age": 30
}
指定したIDのユーザーを削除する
DELETE /api/users/1
指定したIDのユーザー情報を更新する
PUT /api/users/1
Content-Type: application/json
{
"name": "Updated Name"
}
API作成
新しいプロジェクトの作成
フォルダ構成
Program.cs
using System.Data; // System.Data 名前空間を使用するための using ディレクティブ
using Microsoft.Data.SqlClient; // Microsoft.Data.SqlClient 名前空間を使用するための using ディレクティブ
using Npgsql;
internal class Program // プログラムのエントリーポイントを定義する Program クラス
{
private static void Main(string[] args) // アプリケーションのエントリーポイントである Main メソッド
{
var builder = WebApplication.CreateBuilder(args); // WebApplication のビルダーを作成
// コンテナにサービスを追加する
// Swagger/OpenAPI の設定については https://aka.ms/aspnetcore/swashbuckle を参照
builder.Services.AddEndpointsApiExplorer(); // エンドポイントの API Explorer を追加
builder.Services.AddSwaggerGen(); // SwaggerGen を追加
builder.Services.AddControllers(); // コントローラーを追加
// IDbConnection の実装を登録
// PostgreSQLに接続
builder.Services.AddScoped<IDbConnection>((sp) =>
new NpgsqlConnection(builder.Configuration.GetConnectionString("DefaultConnection")));
//SQLserverに接続
//builder.Services.AddScoped<IDbConnection>((sp) =>
//new SqlConnection(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build(); // アプリケーションのビルド
// HTTP リクエスト パイプラインを構成
if (app.Environment.IsDevelopment()) // 開発環境の場合
{
app.UseSwagger(); // Swagger を使用
app.UseSwaggerUI(); // Swagger UI を使用
app.UseDeveloperExceptionPage(); // 開発時の例外ページを使用
}
app.UseHttpsRedirection(); // HTTPS リダイレクションを使用
app.UseRouting(); // ルーティングを使用
// エンドポイントをマッピング
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // コントローラーをエンドポイントにマッピング
});
app.Run(); // アプリケーションを実行
}
}
User.cs
namespace UserAPI.Models
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
}
UsersController.cs
using Microsoft.AspNetCore.Mvc;
using System.Data;
using Dapper;
using UserAPI.Models;
namespace UserAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly IDbConnection _connection;
// IDbConnectionの実装を注入するコンストラクター
public UsersController(IDbConnection connection)
{
_connection = connection;
}
// 全てのユーザーを取得するエンドポイント
[HttpGet]
public async Task<IActionResult> GetAllUsers()
{
// データベースから全てのユーザーを非同期に取得
var users = await _connection.QueryAsync<User>("SELECT * FROM users");
return Ok(users);
}
// 指定IDのユーザーを取得するエンドポイント
[HttpGet("{id}")]
public async Task<IActionResult> GetUserById(int id)
{
// 指定IDのユーザーを非同期に取得
var user = await _connection.QueryFirstOrDefaultAsync<User>("SELECT * FROM users WHERE id = @Id", new { Id = id });
// ユーザーが存在しない場合は404を返す
if (user == null)
return NotFound();
return Ok(user);
}
// 新規ユーザーを追加するエンドポイント
[HttpPost]
public async Task<IActionResult> AddUser(User user)
{
// メールアドレスが既に存在するか確認
var existingUser = await _connection.QueryFirstOrDefaultAsync<User>("SELECT * FROM users WHERE email = @Email", new { Email = user.Email });
if (existingUser != null)
return Conflict("すでにユーザーが存在しています");
// ユーザーを追加
await _connection.ExecuteAsync("INSERT INTO users(name, email, age) VALUES(@Name, @Email, @Age)", user);
// 追加されたユーザーの情報と成功メッセージを返す
return CreatedAtAction(nameof(GetUserById), new { id = user.Id }, "ユーザー作成に成功しました");
}
// 指定IDのユーザーを削除するエンドポイント
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
// 指定IDのユーザーを非同期に取得
var user = await _connection.QueryFirstOrDefaultAsync<User>("SELECT * FROM users WHERE id = @Id", new { Id = id });
// ユーザーが存在しない場合は404を返す
if (user == null)
return NotFound("ユーザーが存在しません");
// ユーザーを削除
await _connection.ExecuteAsync("DELETE FROM users WHERE id = @Id", new { Id = id });
// 削除成功のメッセージを返す
return Ok("削除に成功しました");
}
// 指定IDのユーザー情報を更新するエンドポイント
[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(int id, User user)
{
// 指定IDのユーザーを非同期に取得
var existingUser = await _connection.QueryFirstOrDefaultAsync<User>("SELECT * FROM users WHERE id = @Id", new { Id = id });
// ユーザーが存在しない場合は404を返す
if (existingUser == null)
return NotFound("ユーザーが存在しません");
// 指定IDのユーザーの名前を更新
await _connection.ExecuteAsync("UPDATE users SET name = @Name WHERE id = @Id", new { user.Name, Id = id });
// 更新成功のメッセージを返す
return Ok("更新に成功しました");
}
}
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
//SQLserver 接続文字列
//"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=test;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
//PostgreSQL 接続文字列
"DefaultConnection": "Host=localhost;Port=5432;Username=postgres;Password=YOUR_PASSWORD;Database=test"
}
}
PostgreSQLで上記のUserテーブルを作成する
CREATE TABLE Users (
Id SERIAL PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
Email VARCHAR(255) NOT NULL UNIQUE,
Age INT NOT NULL
);
Id SERIAL PRIMARY KEY: Id列は自動インクリメントされる整数で、主キーとして設定されています。
Name VARCHAR(255) NOT NULL: Name列は最大255文字の文字列で、NULL値は許可されません。
Email VARCHAR(255) NOT NULL UNIQUE: Email列は最大255文字の文字列で、NULL値は許可されず、ユニーク制約が付けられています。
Age INT NOT NULL: Age列は整数で、NULL値は許可されません。
Usersテーブルに新しいユーザーを追加する
INSERT INTO Users (Name, Email, Age) VALUES ('John Doe', 'john@example.com', 30);
実行結果
Try it outを押下
Executeを押下
成功
Discussion