macOSで.NET Coreを使ってAPIサーバをHerokuにデプロイするまでの手順をまとめます。
前提条件
実行環境は macOS Catalina です。
以下のツールはインストール済みとします。
- VS Code
- Docker
何を作るの?
シンプルなTodo管理APIサーバを構築します。データはデータベースに保存します。
.NET Core macOS版のインストール
Microsoftのウェブサイトからダウンロードしてインストールします。
必要な.NETツールをインストール
dotnet tool install --global dotnet-aspnet-codegenerator
dotnet tool install --global dotnet-ef
プロジェクトの作成
webapi
テンプレートを使ってプロジェクトを作成します。
--no-https
をつけないと、デフォルトでlocalhost
の証明書を作る流れになってややこしくなります。
dotnet new webapi -o TodoApi --no-https
初期パッケージのインストール
Entity Framework Coreを使って、データベースへの書き込みを実現するので、以下のようにパッケージをインストールします。
ただ、今回はSQLiteだけ使うので、Microsoft.EntityFrameworkCore.Sqlite
だけインストールしても問題ありません。
cd TodoApi
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.InMemory
初回起動
dotnet run
で起動できます。
dotnet run
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /Users/XXXXX/TodoApi
その後、curl
を以下のように実行するとテンプレートの初期設定であるWeatherForecast
の情報が取得できます。
curl http://localhost:5000/WeatherForecast
次のようなJSONが返されます。
[
{
"date" : "2020-08-01T08:48:53.47458+09:00",
"summary" : "Mild",
"temperatureC" : 39,
"temperatureF" : 102
},
{
"date" : "2020-08-02T08:48:53.474598+09:00",
"summary" : "Mild",
"temperatureC" : -20,
"temperatureF" : -3
},
{
"date" : "2020-08-03T08:48:53.474609+09:00",
"summary" : "Scorching",
"temperatureC" : 47,
"temperatureF" : 116
},
{
"date" : "2020-08-04T08:48:53.474619+09:00",
"summary" : "Scorching",
"temperatureC" : 54,
"temperatureF" : 129
},
{
"date" : "2020-08-05T08:48:53.474629+09:00",
"summary" : "Sweltering",
"temperatureC" : 39,
"temperatureF" : 102
}
]
モデルクラス TodoItem の追加
以下のようにTodoItem.cs
ファイルをModels
フォルダの下に作成します。
public class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
データベースコンテキストの追加
同様にModels
フォルダの下にTodoContext.cs
を作成します。
using Microsoft.EntityFrameworkCore;
namespace TodoApi.Models
{
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options)
: base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; }
}
}
Startup.cs を修正
Startup.cs
を以下のように修正します。ここで先ほど作成したモデルクラスやデータベースコンテキストを登録します。
今回は、SQLiteを使うのでそれ以外をコメントアウトしています。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// 追加
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
namespace TodoApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
//opt.UseInMemoryDatabase("TodoList"));
opt.UseSqlite("Filename=db.sqlite3")); // 今回はこれを使う。 SQLiteのファイル名は db.sqlite3
//opt.UseNpgsql("Host=localhost;Database=mydb;Port=15432;Username=user;Password=password")); // PosgreSQL
//opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // SQL Server
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
コントローラを生成
必要なパッケージを追加します。
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
コントローラTodoItemsController
を生成します。
dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
この状態で自動的にTodoItem
のCRUD APIが実装されます。
データベースマイグレーションとデータベースの更新
dotnet ef migrations add <どんな変更を加えたのかを表す任意の名称>
という形でマイグレーションを作成します。
dotnet ef database update
でデータベースを更新します。
dotnet ef migrations add InitialCreate
dotnet ef database update
APIを試してみる
dotnet run
でサーバを起動します。
POSTのテスト
curl -X POST \
-H "Content-Type:application/json" \
-d '{"Name":"Task 01", "IsComplete":false}' \
http://localhost:5000/api/TodoItems
curl -X POST \
-H "Content-Type:application/json" \
-d '{"Name":"Task 02", "IsComplete":false}' \
http://localhost:5000/api/TodoItems
GETのテスト:一覧取得
curl http://localhost:5000/api/TodoItems
[{"id":1,"name":"Task 01","isComplete":false},{"id":2,"name":"Task 02","isComplete":false}]
PUTのテスト
curl -X PUT \
-H "Content-Type:application/json" \
-d '{"Id":2, "IsComplete":true}' \
http://localhost:5000/api/TodoItems/2
GETのテスト:特定レコードの取得
curl http://localhost:5000/api/TodoItems/2
{"id":2,"name":"Task 02","isComplete":true}
DELETEのテスト
curl -X DELETE \
-H "Content-Type:application/json" \
http://localhost:5000/api/TodoItems/2
{"id":2,"name":"Task 02","isComplete":true}
TodoItemにカラムを追加
以下のようにTodoItem
にCreatedAt
を追加します。
using System; // 追加
public class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
public DateTime CreatedAt { get; set; } // 追加
}
以下のようにマイグレーションを実行します。
dotnet ef migrations add AddDateColumn
dotnet ef database update
データベースが更新されたことを確認
sqlite db.sqlite3
sqlite> PRAGMA table_info('TodoItems');
0|Id|INTEGER|1||1
1|Name|TEXT|0||0
2|IsComplete|INTEGER|1||0
3|CreatedAt|TEXT|1|'0001-01-01 00:00:00'|0
sqlite>
Herokuへデプロイ
以下のようなDockerfile
を作ります。
FROM mcr.microsoft.com/dotnet/core/aspnet
COPY bin/Release/netcoreapp3.1/publish/ App/
WORKDIR /App
CMD export ASPNETCORE_URLS=http://0.0.0.0:$PORT; dotnet TodoApi.dll
デプロイファイルを生成します。
bin/Release/netcoreapp3.1/
配下にリリースようファイル群が生成されます。
dotnet publish -c Release
Herokuのインスタンスを作成して、Dockerfileをpush & releaseします。
heroku create
heroku container:login
heroku container:push web --app <appName>
heroku container:release web --app <appName>
参考
チュートリアル: ASP.NET Core で Web API を作成する
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio-code#prerequisites
チュートリアル: 移行機能の使用 - ASP.NET MVC と EF Core
https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/migrations?view=aspnetcore-3.1
チュートリアル: JavaScript を使用して ASP.NET Core Web API を呼び出す
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/web-api-javascript?view=aspnetcore-3.1
ASP.NET Core を使って Web API を作成する
https://docs.microsoft.com/ja-jp/aspnet/core/web-api/?view=aspnetcore-3.1