LoginSignup
3
3

More than 1 year has passed since last update.

Minimal API 事始め

Last updated at Posted at 2022-12-17

はじめに

C#の簡易アプリが必要になったためRubyのSinatraやPHPのSlim、Flightの用に使える物はないか探してみたら、Minimal APIというものがあるようだったので動かした備忘録になります。
あくまでその時実装した内容についてのまとめになりますので、実運用で必要な機能(Asyncなど)は省いていますのでご了承ください。
まとめようと思ったきっかけは、Postのパラメータの取得方法についてのまとまった記事が見つからなかったためです。(動かすのに1日かかりました)

前提

  • .NET7
  • Ubuntu20.04
  • MySQL8.0

準備

.NETのインストールとMinimal APIの初期化はだいたいドキュメントの通りです

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

Minimal API 初期化

dotnet new web -o SimpleApi

デフォルトで諸々生成されますが、コードの中心になる物は Program.cs になります。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Rootアクセスで Hello World! を返すごくシンプルなAPIです。
上記に変更を加えつつ解説します。

RESTful API

GET 以外に POST PUT DELETE にも対応しています。その場合エントリポイントになるのは以下の通り。

app.MapPost("/users", (Users user) => 何かしらの処理);
app.MapPut("/users/{id}", (int id) => 何かしらの処理);
app.MapDelete("/users/{id}", (int id) => 何かしらの処理);

URLからパラメータを取るPutやDeleteに対し、迷ったのがPostの処理で、この場合URLと対応する名前でClassまたはRecord型のオブジェクトでなければ受け取れません。
https://learn.microsoft.com/ja-jp/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio
のチュートリアルを見る限り、URLの名前の一部が含まれていれば動くようですが、対応させておいた方が無難かもしれません。
Record型ですと以下のように設定します。

訂正。パラメータ名と型があっていれば受け取ることが出来るようです。

record User(int user_id); // 必要なパラメータを列挙
record Characters(int[] chara_ids); // 配列を取得する場合

DB

MySQLアクセスでやったことは以下の通りです。OR/Mなどもありますが、今回は特にOR/Mなど使わずDapperを使用しました。

dotnet add package MySql.Data
dotnet add package Dapper

接続のための設定は大体以下の通り。

appsettings.Development.json

{
  (略)
  "ConnectionStrings": {
    "WebApiDatabase": "server=mysql; database=your_db_host; user=your_user; password=your_password; SslMode=none;"
  }
}

Development で分ける場合、環境変数として
ASPNETCORE_ENVIRONMENTDevelopment を設定してください。
何も設定しない場合 appsettings.Production.json がロードされます。

上記に対して Program.cs

var connectionString = builder.Configuration.GetConnectionString("WebApiDatabase");
var connection = new MySqlConnection(connectionString);
connection.Open();
var selectUserSql = "SELECT COUNT(*) FROM `users` WHERE `user_id` = @UserId;";
var userCount = connection.Query<int>(selectUserSql, new {UserId = userId}).FirstOrDefault<int>();

var transaction = connection.BeginTransaction();
try {
    var insertLogSql = "INSERT INTO `log` (`user_id`) VALUES (@UserId);";
    connection.Execute(insertLogSql, new {UserId = userId});
    transaction.Commit();
} catch (Exception){
    transaction.Rollback();
    return Results.StatusCode(500);
} finally {
    connection.Close();
}

Dapperの詳細な説明は省きます。

CORS

CORSの設定例は以下の通り。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy => {
            policy.WithOrigins("http://localhost", "https://*.your_domain") // サブドメインはワイルドカード可
                .SetIsOriginAllowedToAllowWildcardSubdomains()
                .AllowAnyHeader()
                .AllowAnyMethod();
    });
});
app.UseCors();

WebサーバからTCP接続する場合

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

戻り値

戻り値の設定は以下の簡略設定があります。

var response = new Dictionary<string, dynamic> {
    { "results", results },
};
return Results.Ok(response); //-> 200

return Results.StatusCode(500); //-> 500
return Results.BadRequest("error msg"); // -> 400

ただし上記は全てjsonの戻り値になるため、json以外で返却したい場合は独自でレスポンス設定を記述する必要があります。

Dockerで設定する

Dockerで一括立ち上げしたい場合は以下の通り。

## create out dir
FROM mcr.microsoft.com/dotnet/sdk:7.0-focal AS build
WORKDIR /home/your_home/app
RUN dotnet restore
RUN dotnet publish -c Release -o out

## create csh image
FROM mcr.microsoft.com/dotnet/aspnet:7.0-focal AS runtime
WORKDIR /home/your_home/app

# copy out dir
COPY --from=build /home/your_home/app/out ./out

# set entrypoint
WORKDIR /home/your_home/app/out
# port3000で起動する設定
ENV ASPNETCORE_URLS http://*:3000
ENTRYPOINT ["dotnet", "your_app_name.dll"]

ビルドコンテナとランタイムコンテナが分かれている点が注意。

3
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3