0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C# (.NET Core 5.0) Web API CRUD実装

Last updated at Posted at 2021-05-06

概要

.NET Core 5.0 Web APIサーバを実装して、MySQL接続&CRUD実装をおこなう。

バージョン

Version
.NET Core 5.0
MySQL 8.0.22

簡易設計・実装

簡易設計

MySQL テスト用DB

testデータベースを作成し、以下の2つのテーブルを作成する。

helloテーブル

Field Type Null Key
id int NO PRI
name varchar(128) NO

hello_itemテーブル

Field Type Null Key
id int NO PRI
name varchar(128) NO

API I/F

Resource path HTTP Method Request Body Response Body
/hello GET n/a [{"id": 1, "name": ""}]
/hello POST {"id": 1, "name": ""} {"id": 1, "name": ""}
/hello/{id} PUT {"name": ""} {"id": 1, "name": ""}
/hello/{id} DELETE n/a {"message": "ok"}

設定値の定義

パッケージ

MySQLの8系を利用するとEntityFrameworkCoreの5系では未対応のため、3系を利用する。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <RootNamespace>http_api</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.10" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.10" />
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.22" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
  </ItemGroup>

</Project>

接続情報

※ 本ドキュメントはMySQL接続してCRUDをおこうことが目的のため、Secret情報の考慮はしていません。
appsettings.jsonに接続情報を追加する。

"ConnectionStrings": {
    "DefaultConnection": "Server=127.0.0.1;Database=test;User=root;Password=root;"
}

Entityの実装

定義したテーブルのEntityクラスを実装する。

Hello.cs

public class Hello
{
     public long Id { get; set; }   
     [Required]
     [StringLength(100, ErrorMessage = "Name is within 100 length")]
     public string Name { get; set; }
}

HelloItem.cs

public class HelloItem
{
     public long Id { get; set; }   
     [Required]
     [StringLength(100, ErrorMessage = "Name is within 100 length")]
     public string Name { get; set; }
}

DbContextの実装

Microsoft.EntityFrameworkCoreのDbContextを継承して実装する。
OnModelCreating関数のBuilderでどのEntityがどのテーブルにマッピングするか定義できるので利用する。

Microsoft.EntityFrameworkCore ModelBuilder Class

public class MysqlContext : DbContext
    {
        public MysqlContext(DbContextOptions<MysqlContext> options) : base(options)
        {
            Console.WriteLine("Generated MysqlContext");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<HelloItem>().ToTable("hello_item");
            modelBuilder.Entity<Hello>().ToTable("hello");
        }

        public DbSet<Hello> Hellos { get; set; }

        public DbSet<HelloItem> HelloItems { get; set; }
    }

サーバのServiceCollectionの実装

実装したMysqlContextの接続数は1つとして、1つのConnectionを使い回すようにする。
Startup.csのDbContextPoolでMysqlContextをAddする。

public void ConfigureServices(IServiceCollection services)
{
   ...
   Console.WriteLine(Configuration.GetConnectionString("DefaultConnection"));
   services.AddDbContextPool<MysqlContext>(opt =>
      opt.UseMySQL(Configuration.GetConnectionString("DefaultConnection")));
   ...
}

Controllerの実装

HelloテーブルのCRUDを実装する。
先ほど実装したMysqlContextをSingletonインスタンスで保持するようにDIする。
MysqlContextのコンストラクタに Generated MysqlContext" とログを入れているので、期待値は一度だけ出力されていれば良い。

public class HelloController : ControllerBase
{
    private readonly MysqlContext _mysqlContext;
    
    public HelloController(MysqlContext mysqlContext)
    {
        _mysqlContext = mysqlContext;
        Console.WriteLine("Generated HelloController");
    }

    [HttpGet]
    public List<Hello> Get()
    {
        var list = _mysqlContext.Hellos.ToList();
        return list;
    }

    [HttpPost]
    public Hello Post(Hello hello)
    {
        _mysqlContext.Hellos.Add(hello);
        _mysqlContext.SaveChanges();
        return hello;
    }
    
    [HttpPut("{id}")]
    public Hello Put(long id, Hello hello)
    {
        hello.Id = id;
        _mysqlContext.Hellos.Update(hello);
        _mysqlContext.SaveChanges();
        return hello;
    }
    
    [HttpDelete("{id}")]
    public IDictionary<string, string> Delete(long id)
    {
        var hello = new Hello();
        hello.Id = id;
        _mysqlContext.Hellos.Remove(hello);
        _mysqlContext.SaveChanges();
        
        IDictionary<string, string> map = new Dictionary<string, string>();
        map.Add("message", "ok");
        return map;
    }
}

サーバの起動

実装したAPIサーバを起動する。
バイナリにするまでもないので、runで実行する。

$ dotnet run
Building...
Server=127.0.0.1;Database=test;User=root;Password=root;
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development

動作確認

POST

クライアントのログ。

$ curl -i -X POST \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"test_data01\"}" \
  http://localhost:8080/hello

HTTP/1.1 200 OK
Date: Thu, 06 May 2021 04:00:39 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

{"id":24,"name":"test_data01"}

サーバのログ。
サーバ起動後の初回リクエストにおいて、MySQLのSingletonインスタンスが生成されることでMySQL接続までの時間がレイテンシに乗っていることがわかった。サーバ起動時にMySQLのConnectionをはることができないかは調査が必要。

Generated MysqlContext
Generated HelloController instance

GET

クライアントのログ。

$ curl -i -X GET http://localhost:8080/hello

HTTP/1.1 200 OK
Date: Thu, 06 May 2021 04:03:54 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

[{"id":1,"name":"string"}, {"id":24,"name":"test_data01"}]

サーバのログ。
MysqlContextのログは出力されていないので、使いまわすことができている。

Generated HelloController instance

PUT

クライアントのログ。

$ curl -i -X PUT \
   -H "Content-Type: application/json" \
   -d "{\"name\": \"test_data01_updated\"}" http://localhost:8080/hello/24

HTTP/1.1 200 OK
Date: Thu, 06 May 2021 04:06:09 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

{"id":24,"name":"test_data01_updated"}

サーバのログ。

Generated HelloController instance

DELETE

クライアントのログ。

$ curl -i -X DELETE http://localhost:8080/hello/24

HTTP/1.1 200 OK
Date: Thu, 06 May 2021 04:07:18 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

{"message":"ok"}

サーバのログ。

Generated HelloController instance

所感

サーバ起動時にMySQLに接続しておきたい。
サーバ起動条件の設定を少し調べて、条件満たさない場合のサーバシャットダウン処理等はまた別ドキュメントでまとめていきたい。

0
2
0

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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?