Pada tutorial ini akan dibahas bagaimana cara mengintegrasikan ASP.NET Core Minimal API dengan Entity Framework Core. Untuk database yang digunakan pada tutorial ini adalah Microsoft SQL Server. Pendekatan ORM yang digunakan pada EF adalah Code First.
Membuat Project ASP.NET Core Web API
Pada Visual Studio Code, tambahkan project Web API baru dengan nama CoreBookStoreWebAPI.

Kemudian tambahkan beberapa library dengan menggunakan NuGET Package Manager. Untuk menampilkan jendela NuGet tekan tombol ctrl+shift+P, atau cmd+shift+P (pada MacOS). Pilih NuGet: Open NuGet Gallery


Berikut adalah library yang perlu ditambahkan untuk bekerja dengan EF Core.
-Microsoft.EntityFrameworkCore
-Microsoft.EntityFrameworkCore. SqlServer
-Microsoft.EntityFrameworkCore.Tools
-Microsoft.EntityFrameworkCore.Design
Pada file .csproj dapat dilihat bahwa ada beberapa referensi pustaka yang sudah ditambahkan pada project ini.
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
Pada Solution Explorer juga dapat dilihat daftar package yang telah diinstall seperti pada gambar di bawah ini.

Konfigurasi Koneksi Ke Database
Langkah selanjutnya adalah membuat file yang menyimpan informasi untuk melakukan koneksi ke database SQL Server. Informasi ini disimpan pada file appsettings.json.
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost,1433;Database=BookStoreDb;User Id=sa;Password=<password>;MultipleActiveResultSets=true;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Menambahkan Model
Langkah selanjutnya adalah menambahkan folder Models pada project, kemudian tambahkan class Author yang akan digunakan untuk menyimpan informasi tentang Author. Kode untuk class Author adalah sebagai berikut:
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Selain class Author yang merepresentasikan data Author, buat juga class Book yang akan digunakan untuk menyimpan data buku yang ditulis oleh Author. Untuk kode dari class Book adalah sebagai berikut:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public DateTime PublishDate { get; set; }
public decimal BasePrice { get; set; }
}
Pada dua class yang sudah dibuat dapat dilihat bahwa kedua class tersebut memiliki properti Id untuk menympan data yang unik dari masing-masing entitas. Untuk standarisasi aturan yang ada pada EF disarankan untuk menggunakan nama table kemudian diikuti dengan Id untuk penamaan propertinya. Jika class ini nanti digenerate menjadi tabel (menggunakan metode code first) maka properti-properti dalam class tersebut akan di mapping menjadi tabel.
Menambahkan Data Context Class
Untuk melakukan koneksi ke database perlu dibuat sebuah class yang menangani hal tersebut. Pada EF Core class DbContext digunakan untuk mengakses objek yang terhubung dengan database. Pada DbContext class-class yang akan di mapping menjadi table di database dapat ditambahkan. Untuk itu buat folder Data, kemudian tambahkan DbContext class dengan nama PubContext.cs. Tambahkan kode berikut pada file PubContext.cs.
public class PubContext : DbContext
{
public PubContext(DbContextOptions options):base(options)
{}
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
}
Pada kode diatas dapat dilihat bahwa class PubContext yang akan dgunakan sebagai DbContext harus diturunkan dari class DbContext. Kemudian tambahkan properti dengan tipe DbSet<Nama Class> yang akan di mapping sebagai tabel pada database.
Mendaftarkan EF DataContext pada Program.cs
Setelah class DbContext dibuat, langkah selanjutnya adalah meregister class DbContext sebagai services. Tambahkan EF Data Context services pada Program.cs, agar object Data Context mengetahui default database connection yang akan digunakan.
builder.Services.AddDbContext<PubContext>(options => options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
Menjalankan EF Migrations
Cara yang dapat digunakan untuk menjalankan EF Migrations yaitu menggunakan dotnet CLI pada jendela terminal di Visual Studio Code.
Pada EF Core ada dua cara untuk bekerja dengan database yaitu metode Code First dan Database First. Metode Code First dapat digunakan jika anda akan membuat project baru, dengan menggunakan Code First, anda dapat mendefinisikan terlebih dahulu class model yang nanti akan digenerate menjadi tabel di database. Misal pada
Jalankan EF Migrations dengan mengetikan perintah berikut:
dotnet ef migrations add "InitialCreate"
Jika perintah tersebut berhasil dijalankan, maka folder Migrations akan dibuat pada project.

Folder Migrations tersebut berisi file-file database script yang akan dapat dieksekusi ketika akan membuat tabel-tabel-nya di database.
Untuk mengeksekusi file SQL pada folder Migrations jalankan perintah berikut:
dotnet ef database update
Jika perintah migrasi diatas berhasil untuk dijalankan, maka tabel-nya akan dibuat di database. Anda dapat melihat hasil database yang dibuat dengan menggunakan SQL Server Management Studio atau Azure Data Studio.
Buka Azure Data Studio, kemudian koneksikan ke database BookStoreDb. Berikut adalah database dan tabel yang berhasil dibuat menggunakan perintah migrations.

Dapat dilihat bahwa dua tabel Authors dan Books sudah berhasil dibuat. Field yang ada pada tabel tersebut juga sama dengan properti yang sudah anda buat di class model. Tabel __EFMigrationHistory digunakan untuk menyimpan informasi versi migrasi dari EF Migrations.
Menambahkan Data Layer
Pada contoh project yang dibuat akan menggunakan repository pattern. Repository pattern digunakan untuk menambahkan kode yang berhubungan dengan koneksi dan manipulasi database. Ini bertujuan agar API Controller tetap simple dan mudah dibaca. Untuk menambahkan data layer, buat interface IAuthor pada folder data dengan method sebagai berikut:
public interface IAuthor
{
Task<IEnumerable<Author>> GetAll();
Task<Author> Insert(Author author);
Task<Author> GetById(int id);
Task<Author> Update(Author author);
Task Delete(int id);
}
Method diatas digunakan untuk operasi CRUD (Create, Read, Update, Delete) yang akan dilakukan di database. Kemudian tambahkan class AuthorDAL.cs yang berisi implementasi dari interface tersebut sebagai berikut:
public class AuthorDAL : IAuthor
{
private readonly PubContext _context;
public AuthorDAL(PubContext context)
{
_context = context;
}
public async Task Delete(int id)
{
try
{
var deleteAuthor = await GetById(id);
_context.Authors.Remove(deleteAuthor);
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
throw new Exception($"{ex.Message}");
}
}
public async Task<IEnumerable<Author>> GetAll()
{
var authors = await _context.Authors.ToListAsync();
return authors;
}
public async Task<Author> GetById(int id)
{
var author = await _context.Authors.Where(a => a.Id == id).FirstOrDefaultAsync();
if (author != null)
return author;
else
throw new Exception($"Author with id {id} not found");
}
public async Task<Author> Insert(Author author)
{
try
{
_context.Authors.Add(author);
await _context.SaveChangesAsync();
return author;
}
catch (Exception ex)
{
throw new Exception($"{ex.Message}");
}
}
public async Task<Author> Update(Author author)
{
try
{
var updateAuthor = await GetById(author.Id);
updateAuthor.FirstName = author.FirstName;
updateAuthor.LastName = author.LastName;
await _context.SaveChangesAsync();
return updateAuthor;
}
catch (Exception ex)
{
throw new Exception($"{ex.Message}");
}
}
}
Kode diatas berisi statement Lambda untuk operasi CRUD pada tabel Author di database. Untuk mengakses object DataContext yang sudah dibuat pada folder Data, maka dapat dilakukan teknik Dependency Injection dengan menginject object pada class konstruktor. Untuk operasi SQL yang akan dikirimkan ke tabel di database digunakan LINQ Method. LINQ Method yang digunakan akan secara otomatis di konversi menjadi T-SQL sintaks oleh EF Core.
Menambahkan DI Services pada Program.cs
Agar anda dapat menggunakan class AuthorDAL yang sudah dibuat pada controller, maka perlu ditambahkan registrasi Dependency Injection class pada file Program.cs. Tambahkan kode berikut pada Program.cs.
builder.Services.AddScoped<IAuthor, AuthorDAL>();
Menambahkan Minimal API (Method GET)
Berbeda dengan ASP.NET Web API yang menggunakan MVC pattern, Minimal API tidak menggunakan Cotroller, jadi semua method akan dibuat pada file Program.cs
Untuk membuat method yang menampilkan seluruh data Author tambahkan kode berikut pada Program.cs.
app.MapGet("api/v1/authors", async (IAuthor authorDal) =>
{
var authors = await authorDal.GetAll();
return Results.Ok(authors);
});
Method MapGet() digunakan untuk melakukan request dengan method GET, cara penulisan ini lebih sederhana dan simpel jika dibandingkan dengan method yang menggunakan MVC pattern.
Alamat endpoint dari API juga langsung dituliskan pada method MapGet() “api/v1/authors”.
Jalankan web api kemudian lakukan tes pada API yang sudah dibuat untuk menampilkan semua data author.

Minimal API dengan Method GET & Parameter
Contoh berikut akan menunjukan bagaimana cara menggunakan method GET dengan parameter Id yang mengembalikan satu data author.
Pada file Program.cs tambahkan method berikut:
Contoh berikut akan menunjukan bagaimana cara menggunakan method GET dengan parameter Id yang mengembalikan satu data author. Pada file Program.cs tambahkan method berikut:
app.MapGet("api/v1/authors/{id}", async (IAuthor authorDal, int id)=>
{
var author = await authorDal.GetById(id);
if (author == null)
{
return Results.NotFound();
}
return Results.Ok(author);
});
Method diatas akan menerima parameter id dan mengembalikan satu data author sesuai dengan id yang diinputkan. Jalankan web api kemudian lakukan tes pada API yang sudah dibuat.


Minimal API dengan Method POST
Contoh berikut akan menunjukan bagaimana cara menambahkan data menggunakan method POST pada Minimal API. Tambahkan method berikut pada Program.cs
app.MapPost("api/v1/authors", async (IAuthor authorDal,
Author author) =>
{
var newAuthor = await authorDal.Insert(author);
return Results.Created($"/api/v1/authors/{newAuthor.AuthorId}", newAuthor);
});
Method diatas akan menerima parameter bertipe Author, dan akan mengembalikan http status 201 jika berhasil untuk menambahkan data.
Jalankan web api kemudian lakukan tes pada API yang sudah dibuat.


Minimal API dengan Method PUT
Contoh berikut akan menunjukan bagaimana cara mengupdate data / memodifikasi resources menggunakan method PUT pada Minimal API. Tambahkan method berikut pada Program.cs.
app.MapPut("api/v1/authors/{id}", async (IAuthor authorDal,
Author author) =>
{
var editAuthor = await authorDal.GetById(author.AuthorId);
if (editAuthor == null)
{
return Results.NotFound();
}
var updatedAuthor = await authorDal.Update(author);
return Results.Ok(updatedAuthor);
});
Pada method diatas hal yang pertama akan dilakukan adalah memastikan apakah ada author yang akan diupdate, baru kemudian mengupdate data sesuai dengan data baru yang dikirimkan. Jika proses berhasil maka method ini akan mengirimkan http status 200 OK. Jalankan web api kemudian lakukan tes pada API yang sudah dibuat.


Minimal API dengan Method DELETE
Contoh berikut akan menunjukan bagaimana cara menghapus data menggunakan method DELETE pada Minimal API. Tambahkan method berikut pada Program.cs.
app.MapDelete("api/v1/authors/{id}", async (IAuthor authorDal,
int id) =>
{
var author = await authorDal.GetById(id);
if (author == null)
{
return Results.NotFound();
}
await authorDal.Delete(id);
return Results.NoContent();
});
Pada method diatas hal yang pertama akan dilakukan adalah memastikan apakah author yang akan delete ditemukan, berikutnya adalah mendelete data author sesuai dengan id parameter. Jalankan web api kemudian lakukan tes pada API yang sudah dibuat.


Leave a comment