In this blog post I wanted to cover how to use Redis with AspNetCore WebAPI. Most of my examples have been covering using console application since I wanted to explain the core concepts of Redis and the functionality. Now lets see how you can use it in a Web Application.
Create the webapi
To start we will create webapi using command line dotnet new
1 2 3 4 5 6 7 8 9 10 11 12 |
$mkdir RedisAspDotNetCoreWebApiSample $cd RedisAspDotNetCoreWebApiSample $ dotnet new webapi The template "ASP.NET Core Web API" was created successfully. Processing post-creation actions... Running 'dotnet restore' on C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj... Restore completed in 1.05 sec for C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj. Restore succeeded. |
Now that we have our skeleton created, we need to add some of the dependency for Redis. I have used dotnet command line again to add the dependencies. I am also using Message Pack for my serialization, there are other options also like Newtonsoft etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ dotnet add package StackExchange.Redis.Extensions.AspNetCore --version 5.0.3 info : Adding PackageReference for package 'StackExchange.Redis.Extensions.AspNetCore' into project 'C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : Installing System.Runtime.CompilerServices.Unsafe 4.5.2. info : Installing Pipelines.Sockets.Unofficial 2.0.22. info : Installing StackExchange.Redis 2.0.601. info : Installing StackExchange.Redis.Extensions.Core 5.0.3. info : Installing Microsoft.Extensions.Configuration.Binder 2.2.4. info : Installing StackExchange.Redis.Extensions.AspNetCore 5.0.3. info : Package 'StackExchange.Redis.Extensions.AspNetCore' is compatible with all the specified frameworks in project 'C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : PackageReference for package 'StackExchange.Redis.Extensions.AspNetCore' version '5.0.3' added to file 'C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : Committing restore... info : Writing assets file to disk. Path: C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\obj\project.assets.json log : Restore completed in 11.14 sec for C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj. |
1 2 3 4 5 6 7 8 9 |
> dotnet add package StackExchange.Redis.Extensions.MsgPack --version 5.0.3 info : Adding PackageReference for package 'StackExchange.Redis.Extensions.MsgPack' into project 'C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : Installing StackExchange.Redis.Extensions.MsgPack 5.0.3. info : Package 'StackExchange.Redis.Extensions.MsgPack' is compatible with all the specified frameworks in project 'C:GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : PackageReference for package 'StackExchange.Redis.Extensions.MsgPack' version '5.0.3' added to file 'C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj'. info : Committing restore... info : Writing assets file to disk. Path: C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\obj\project.assets.json log : Restore completed in 19.02 sec for C:\GitHub\RedisForNetDevelopers\14.RedisAspDotNetCore\RedisAspDotNetCoreWebApiSample\RedisAspDotNetCoreWebApiSample.csproj. |
Running Redis in Docker
I am using Docker to run my Redis server, the command to execute to run my redis server as below
1 |
$docker run --name redis-server -p6379:6379 -d redis |
Now we will need our aspnetcore information on how to connect to redis, the best option is to use your appsettings.json file to have the information. For production you will probably like to store it in some external configuration management like Hashicorp Vault or Azure Vault.
Open up your appsettings.json file and add the Redis configuration information. One can add multiple Hosts in the array, for us we only have 1 server running on localhost.
1 2 3 4 5 6 7 8 9 10 11 12 |
"Redis": { "AllowAdmin": true, "Ssl": false, "ConnectTimeout": 6000, "ConnectRetry": 2, "Database": 0, "Hosts": [ { "Host": "localhost", "Port": "6379" }] } |
Redis AspNetCore WebApi
Now we need to configure our webapi to start using redis, we will modify our Startup.cs file and use the build in IoC (Dependency Injection) container that it provides to hook things up in our ConfigureServices method.
1 2 3 4 5 6 7 8 9 10 11 |
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); var redisConfiguration = Configuration.GetSection("Redis").Get<RedisConfiguration>(); services.AddSingleton(redisConfiguration); services.AddSingleton<IRedisCacheClient,RedisCacheClient>(); services.AddSingleton<IRedisCacheConnectionPoolManager, RedisCacheConnectionPoolManager>(); services.AddSingleton<IRedisDefaultCacheClient, RedisDefaultCacheClient>(); services.AddSingleton<StackExchange.Redis.Extensions.Core.ISerializer, StackExchange.Redis.Extensions.MsgPack.MsgPackObjectSerializer>(); } |
Create a Controller
Lets add a new controller and call it RedisController, we will use the controller to call redis to store some values and to get some values out of redis. The sample below shows a HttpGet, HttpPost and a HttpDelete method decorated attribute. As you may also notice that the IRedisCacheClient was injected into the constructor by the IoC Container when we configured our services in Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; using StackExchange.Redis.Extensions.Core.Abstractions; namespace RedisAspDotNetCoreWebApiSample.Controllers { [Route("api/[controller]")] [ApiController] public class RedisController: ControllerBase { private readonly IRedisCacheClient _redis; public RedisController(IRedisCacheClient redis) { _redis = redis; } [HttpPost] public IActionResult Post(User fakeuser) { var user = new User() { Firstname = "Taswar", Lastname = "Bhatti", Twitter = "@taswarbhatti", Blog = "http://taswar.zeytinsoft.com" }; bool added = _redis.Db0.Add("user:key", user, DateTimeOffset.Now.AddMinutes(10)); if(added) return Ok(); else return BadRequest("Cannot add user"); } [HttpGet] public ActionResult<IEnumerable<User>> Get() { var users = _redis.Db0.GetAll<User>(new string[] {"user:key"}); return users.Values.ToList(); } // DELETE api/redis/5 [HttpDelete("{key}")] public ActionResult Delete(string key) { var result = _redis.Db0.Remove(key); if(result) return Ok(); else return BadRequest("Cannot delete user"); } } public class User { public string Firstname { get; set;} public string Lastname { get; set;} public string Twitter { get; set;} public string Blog { get; set;} } } |
Testing the methods
I used curl to test out the method, first I used the POST method to create the data I wanted. I am using the -k prefix since I wanted to ignore the cert and I just posted some random json data into the method, even though in the method I don’t use it as above, but just to give an example of how you would pass in data.
1 |
$curl -k -H "Content-Type: application/json" -XPOST https://localhost:5001/api/redis -d '{"name":"Taswar"}' |
Now I can call the get call to get the data, one can use curl or just use chrome to call the get call. The result are show below.
1 2 3 4 5 6 7 8 9 |
// https://localhost:5001/api/redis [ { "firstname": "Taswar", "lastname": "Bhatti", "twitter": "@taswarbhatti", "blog": "http://taswar.zeytinsoft.com" } ] |
Calling StackExchange.Redis Api
What if we want to call Redis StackExchange calls directly? We can do so like below I am using the SetAdd method and SetMembers to get values out of Redis Sets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//Sample below uses the Redis method directly from StackExchange [HttpPost] [Route("db/create")] public IActionResult CreateSet() { //create using Redis Commands bool added = _redis.Db0.Database.SetAdd("setkey","1"); if(added) return Ok(); else return BadRequest("Cannot add user"); } //Sample below uses the Redis method directly from StackExchange [HttpGet] [Route("db/getset")] public ActionResult<string> GetSet() { var setValues = _redis.Db0.Database.SetMembers("setkey"); return string.Join(",", setValues); } |
Summary
I hope this explain how to use redis with your aspnetcore application, you can get the source code for this project on github. https://github.com/taswar/RedisForNetDevelopers/tree/master/14.RedisAspDotNetCore. Also feel free to comment on it and ask questions, if there is something missing feel free to reach out.
Hi
I am using .net 6 and StackExchange Redis AspNetCore version 8.0.3
I am not able to find IRedisCacheClient. Could you please provide source code for this ?
The extension is from here https://github.com/imperugo/StackExchange.Redis.Extensions
You will need to contact @imperugo for it or comment it on their github account fir support but here is the IRedisClient
https://github.com/imperugo/StackExchange.Redis.Extensions/blob/c422cac133773b3f4f182cae418681f632df4fa8/src/core/StackExchange.Redis.Extensions.Core/Abstractions/IRedisClient.cs