Asp.Net Core ile Rest API Oluşturma
Günümüzde Rest API’ler uygulamalarımızın istediğimiz uçlarını başka uygulamalara (mobil vb.) açmanın standart yolu haline gelmeye başladı, hatta geldi diyebiliriz.
Bende bu yazımda Visual Studio 2019 kullanarak Asp.Net Core ile nasıl bir Rest Api oluşturacağız onu anlatmaya çalışacağım.
Senaryomuz da Api görevlerimiz, Üretim İş Emirlerini oluşturabilecek, var olan iş emirlerini listeleyebilecek, silebilecek ve güncelleyebilecektir.
Makalede yaptığımız projeye Github sayfamdan ulaşabilirsiniz.
Asp.NET Core Web Application Projesi Oluşturun
Visual Studio’yu açarak yeni proje oluşturma aşamasında Asp.Net Core Web Application projesi oluşturuyoruz.
Next diyerek ilerliyor, proje bilgilerimizi girdikten sonra Create deyip projemizi oluşturuyoruz, bu aşamadan sonra gelen ekrandan API seçerek devam ediyoruz.
Şimdi modelimizi oluşturarak başlıyoruz, bunun için öncelikle projenin kök dizinine “Models” isimli bir klasör oluşturuyoruz ve içerisine “ProductionOrder” isimli class oluşturuyoruz.
public class ProductionOrder
{
public int Id { get; set; }
public string ProductionStockNo { get; set; }
public string OrderNo { get; set; }
public DateTime CreateDate { get; set; }
}
Daha sonra “Services” isimli bir klasör daha oluşturuyoruz, iş emirlerimizi kaydetmek için “EF Core: In-memory data provider” kullanacağız. Bunun amacı Api test etmek için veritabanı oluşturarak zaman kaybetmemek, bunun yerine memoryi database olarak kullanmak, daha sonra istersek bunu Veritabanı gibi kalıcı bir depolama birimiyle hızlıca değiştirebiliriz.
Entity Framework Core ayarlamasını yapmamız gerekiyor bunun için projede sağ tıklayarak “Magane Nuget Packet” seçiyoruz ve ardından “Browse” alanında “Microsoft.EntityFrameworkCore.InMemory” yazarak çıkan paketi ekliyoruz.
Şimdi “Models” klasörüne “ProductionOrdersAPIContext” isminde bir class oluşturarak “DbContext” uygulamamız ile veri sağlayacımız arasındaki iletişimi sağlayacağız.
Bunu class içerisine eklemeyi unutmayın;
“using Microsoft.EntityFrameworkCore;”
public ProductionOrdersAPIContext(DbContextOptions options) : base(options)
{
}
public DbSet<ProductionOrder> ProductionOrders { get; set; }
Şimdi proje kökünde bulunan “Startup” classında, “MemoryDatabase” bağlantısını yapılandırıyoruz.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<ProductionOrdersAPIContext>(x => x.UseInMemoryDatabase());
services.AddTransient<IProductionOrderRepository, InMemoryProductionOrderRepository>();
services.AddMvc();
}
“Services” klasörü altında “IProductionOrderRepository” adında bir interface oluşturuyoruz.
public interface IProductionOrderRepository
{
ProductionOrder Add(ProductionOrder productionorder);
IEnumerable<ProductionOrder> GetAll();
ProductionOrder GetById(int id);
void Delete(ProductionOrder productionorder);
void Update(ProductionOrder productionorder);
}
“Services” klasörümüz altına in-memory veritabanımız ile haberleşmesi için “InMemoryProductionOrderRepository” isimli bir class daha oluşturuyoruz.
public class InMemoryProductionOrderRepository : IProductionOrderRepository
{
private readonly ProductionOrdersAPIContext _context;
public InMemoryProductionOrderRepository(ProductionOrdersAPIContext context)
{
_context = context;
}
public ProductionOrder Add(ProductionOrder productionorder)
{
var addedProductionOrder = _context.Add(productionorder);
_context.SaveChanges();
productionorder.Id = addedProductionOrder.Entity.Id;
return productionorder;
}
public void Delete(ProductionOrder productionorder)
{
_context.Remove(productionorder);
_context.SaveChanges();
}
public IEnumerable<ProductionOrder> GetAll()
{
return _context.ProductionOrders.ToList();
}
public ProductionOrder GetById(int id)
{
return _context.ProductionOrders.SingleOrDefault(x => x.Id == id);
}
public void Update(ProductionOrder productionorder)
{
var productionorderToUpdate = GetById(productionorder.Id);
productionorderToUpdate.ProductionStockNo = productionorder.ProductionStockNo;
productionorderToUpdate.OrderNo = productionorder.OrderNo;
productionorderToUpdate.CreateDate = productionorder.CreateDate;
_context.Update(productionorderToUpdate);
_context.SaveChanges();
}
}
Artık Data Layerimizi ayarladığımıza göre Web Api controllerimize girişebiliriz.
Web API Controller Oluşturma;
Öncelikle başlamadan projeyi ilk oluşturduğumuz da default olarak oluşan “Controller” altında ki “ValuesController” dosyamızı silelim. Ayrıca “Properties” altında ki “launchSettings.json” dosyamızın içeriğini aşağıdaki gibi değiştirelim.
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:63595/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "productionorder",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ProductionOrdersAPI": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/productionorder",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Şimdi “Controllers” klasörü içerisine “ProductionOrderController” isimli bir class oluşturuyoruz.
[Route("[controller]")]
public class ProductionOrderController : Controller
{
private readonly IProductionOrderRepository _productionorderRepository;
public ProductionOrderController(IProductionOrderRepository productionorderRepository)
{
_productionorderRepository = productionorderRepository;
}
// GET: book
[HttpGet]
public IEnumerable<ProductionOrder> Get()
{
return _productionorderRepository.GetAll();
}
// GET book/5
[HttpGet("{id}", Name = "GetProductionOrder")]
public IActionResult Get(int id)
{
var productionorder = _productionorderRepository.GetById(id);
if (productionorder == null)
{
return NotFound();
}
return Ok(productionorder);
}
// POST book
[HttpPost]
public IActionResult Post([FromBody]ProductionOrder value)
{
if (value == null)
{
return BadRequest();
}
var createdProductionOrder = _productionorderRepository.Add(value);
return CreatedAtRoute("GetProductionOrder", new { id = createdProductionOrder.Id }, createdProductionOrder);
}
// PUT book/5
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody]ProductionOrder value)
{
if (value == null)
{
return BadRequest();
}
var note = _productionorderRepository.GetById(id);
if (note == null)
{
return NotFound();
}
value.Id = id;
_productionorderRepository.Update(value);
return NoContent();
}
// DELETE book/5
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var productionorder = _productionorderRepository.GetById(id);
if (productionorder == null)
{
return NotFound();
}
_productionorderRepository.Delete(productionorder);
return NoContent();
}
}
Bu framework bizim için otomatik kodlar üretti, aşağıda http metotlarıyla yapabileceklerimizin listesi mevcut.
URL | Verb | Aksiyon |
/productionorder | GET | Bütün iş emirlerini getirir. |
/productionorder/{id} | GET | Id verilen iş emrini getirir. |
/productionorder | POST | Yeni iş emri oluşturur. |
/productionorder/{id} | PUT | Id verilen iş emrini günceller. |
/productionorder/{id} | DELETE | Id verilen iş emrini siler. |
Postman ile test;
Evet, şimdi API kullanıma hazır, test ederek ne kadar doğru çalıştığını kontrol edebiliriz.
Test için ben Postman uygulamasını kullanacağım, öncelikle Visual Studio’da uygulamamızı IIS Express ile run ederek Postman’i açıyoruz ve GET olarak http://localhost:63595/productionorder linkine istekte bulunuyoruz. (Portu değiştirdiyseniz kendine göre düzenlemeniz gerekmektedir.)
Status 200 ile cevap gelmesi gerekiyor, gelen cevap boş olacaktır çünkü henüz bir iş emri create etmedik.
Şimdi yine API kullanarak bir Üretim İş Emri create edelim bu defa POST kullanacağız.
Body alanında raw ve Json seçerek aşağıdaki json isteğimizi yazarak Send yapıyoruz.
{
"ProductionStockNo":"MLZ-01-01",
"OrderNo":"0001",
"CreateDate":"07/01/2019"
}
İstekte bulunduktan sonra bize oluşturduğumuz İş Emrini ve otomatik olarak verdiği Id numarasını geri dönüyor.
Şimdi tekrar Get ile kayıtlı iş emirlerini istediğimizde bize boş dönmeyecektir.
Aynı şekilde PUT, DELETE kullanarak da güncelleme ve silme işlemlerini yapabilir durumdasınız.
Fakat farkındaysanız oluşturduğumuz projede tamamen herkese açık bir API oldu. Yani herkes iş emri ekleyebilir, silebilir ve listeleyebilir durumda, bunu engellemek için Okta kullanarak JWT authentication (kimlik doğrulaması) ekleyerek token ile çalışmayı bir sonra ki makalede bu proje üzerinden anlatacağım.