Merhaba sevgili okur,
ASP.NET Core uygulamaları için redis’de temel okuma-yazma-silme işlemlerini nasıl gerçekleştirebileceğinizi açıklamaya çalıştım.

Hemen bir ASP.NET Core Web API projesi oluşturalım.

dotnet new webapi --name "Example"

Projemiz de redis’in temel özelliklerini kullanmak için gerekli nuget paketini projeye dahil ediyoruz.

Not: Daha geniş kapsam da redis API’sini kullanmamıza olanak sağlayan paketler bulunuyor. İkinci bölümde detaylı olarak yer vereceğim.

dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis --version 3.1.10

İlgili paketi projeye ekledikten sonra “Startup.cs” dosyasında bulunan servis tanımlarından “DistributedCache” servisini aktif hale getiriyoruz. Tanımlama yaparken yapılandırma ayarları bölümünde kullanacağamız redis’e ait host ve port bilgilerini yazıyoruz.

services.AddStackExchangeRedisCache(option =>
{
  option.Configuration = "localhost:6379";
});

Not: Host, port, connection string veya benzer bilgileri code içerisinde kullanmamaya özen gösterelim.

// appsettings.json
{
  "Redis": {
    "Host": "localhost",
    "Port": "6379"
  }
}

Bağımlılık enjeksiyonu (Dependency Injection) yardımıyla IConfiguration arayüzü (interface) ile gelen methodları kullanarak redis bilgilerini artık “appsettings.json” dosyasından okuyoruz.

services.AddStackExchangeRedisCache(option =>
{
  option.Configuration = $”{Configuration[“Redis:Host”]}:{Configuration[“Redis:Port”]}”;
});
using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ProjectRedis { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddStackExchangeRedisCache(option => { option.Configuration = $"{Configuration["Redis:Host"]}:{Configuration["Redis:Port"]}"; }); Console.WriteLine($"{Configuration["Redis:Host"]}:{Configuration["Redis:Port"]}"); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }

Redis üzerinde örnek işlemleri gerçekleştirmek adına user endpoint’lerini tanımlıyoruz. İlgili class’ın constructor’ın da IDistributedCache arayüzünü (interface) bağımlılık enjeksiyonu (Dependency Injection) yardımıyla geçiyoruz.

using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; namespace Example.Controllers { [ApiController] [Route("[controller]")] public class UsersController : ControllerBase { private readonly IDistributedCache _distributedCache; public UsersController(IDistributedCache distributedCache) { _distributedCache = distributedCache; } [HttpGet] public IActionResult Get() { return Ok(); } [HttpPost] public IActionResult Post() { return Ok(); } [HttpDelete] public IActionResult Delete() { return Ok(); } } }

IDistributedCache arayüzü ile gelen temel redis methodları şu an için ihtiyacımızı karşılıyor. Eklemiş olduğumuz nuget paketi Microsoft tarafından redis’in temel özelliklerini kullanmamız için geliştirilmiş olup ileri seviye özellikler için kullanılmamaktadır.

Evet artık yazma-okuma gibi işlemleri yapabiliriz. “SetString” method’unu kullanarak o an ki tarih-saat bilgisini string olarak redis’e yazıyoruz. Kullanılan method’ların async versiyonları da bulunuyor.

_distributedCache.SetString(“DATE_NOW”, DateTime.Now.ToString());

await _distributedCache.SetStringAsync(“DATE_NOW”, DateTime.Now.ToString());

Redis de bulunan “DATE_NOW” key’e ait değeri “GetString” medhod’unu kullanarak okuyoruz.

var DATE_NOW = _distributedCache.GetString(“DATE_NOW”);

“DATE_NOW” key’ini siliyoruz.

_distributedCache.Remove("DATE_NOW");

Veri oluşturulduktan sonra verilen süre sonunda otomatik olarak redis’den silinir.

var options = new DistributedCacheEntryOptions
{
  AbsoluteExpiration = DateTime.Now.AddSeconds(10)
};

_distributedCache.SetString("DATE_NOW", DateTime.Now.ToString(), options);

Bir complex type’ı redis’e yazmak için “Json” veya “Binary” serialize işlemlerininden birini tercih edebilirsiniz. Fakat genelde “Json” serialize yöntemi kullanılır. “Binary” serialize genelde dosyalarla ilgili işlemler de tercih edilir.

Hemen bir user model class’ı ekliyoruz.

// User.cs
public class User
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

Class’ımızdan bir nesne örneği alıyoruz.

var user = new User {
  Id = 1,
  FirstName = "Anıl",
  LastName = "Atalay"
};

User model class’ımızı json serialize işlemi yapmak için projemize bir nuget paketi ekliyoruz. İlgili paket Asp.Net Core API projelerinde varsayılan olarak gelmiyor!

dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson --version 3.1.10

Json serialize işlemini gerçekleştiriyoruz.

var userData = JsonConvert.SerializeObject(user);

Artık elimizde bulunan string user datasını redis’e yazabiliriz. Birden fazla user yazılabilir düşüncesi ile benzersiz bir key oluşturuyoruz.

await _distributedCache.SetStringAsync($”USER_{user.Id}”, userData);

Redis’e yamış olduğumuz user nesnesini okuyalım.

var userData = await _distributedCache.GetStringAsync("USER_1");

Gelen user string datasını User class’ına deserialize işlemi gerçekleştireceğiz.

var user = JsonConvert.DeserializeObject<User>(userData);

Benzer işlemleri binary içinde yapalım. User nesnemizin json string halini byte dizisine çeviriyoruz ve “SetAsync” method’unu kullanarak redis’e yazıyoruz.

var user = new User
{
  Id = 1,
  FirstName = "Anıl",
  LastName = "Atalay"
};

var userData = JsonConvert.SerializeObject(user);

var userByte = Encoding.UTF8.GetBytes(userData);

await _distributedCache.SetAsync($"USER_{user.Id}", userByte);

Redis’den okurken ise, yazarken yaptığımız işlemlerin tersini yapıyoruz.

var userByte = await _distributedCache.GetAsync("USER_1");

var userData = Encoding.UTF8.GetString(userByte);

var user = JsonConvert.DeserializeObject<User>(userData);

Redis üzerinde temel işlemleri gerçekleştirdik. Artık oluşturmuş olduğumuz projeye devam edelim. En son user endpoint’lerini eklemiştik. GET, POST ve DELETE işlemlerine başlayalım.

using System.Threading.Tasks; using Example.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using Newtonsoft.Json; namespace Example.Controllers { [ApiController] [Route("[controller]")] public class UsersController : ControllerBase { private readonly IDistributedCache _distributedCache; public UsersController(IDistributedCache distributedCache) { _distributedCache = distributedCache; } [HttpGet("{id}")] public async Task Get([FromRoute] int id) { if (id == default) return NotFound(); var userData = await _distributedCache.GetStringAsync($"USER_{id}"); if (userData == null) return NotFound("User not found."); var user = JsonConvert.DeserializeObject(userData); return Ok(user); } [HttpPost] public async Task Post([FromBody] User user) { if (user == null) return BadRequest(); var userKey = $"USER_{user.Id}"; var userData = JsonConvert.SerializeObject(user); await _distributedCache.SetStringAsync(userKey, userData); return Ok(user); } [HttpDelete("{id}")] public async Task Delete([FromRoute] int id) { if (id == default) return NotFound(); await _distributedCache.RemoveAsync($"USER_{id}"); return Ok(id); } } }

Evet artık user endpoint’leri üzerinden redis’e veri yazabiliyoruz. Gerçek dünya da bu işlemler veritabanı ile gerçekleştirilir. Uygulamamızın yapısına bağlı olarak süreç değişebilir. İlk isteği veritabanı üzerinden çekip dönebilir, daha sonra veriyi redis’e yazıp diğer isteklere redis’de ki veriler ile cevap verilebilir.

Öğrenilecek çok şey, gezilecek çok yer var. Bir sonraki postumda görüşmek üzere.