ASPNET 7 - Output Cache

2022. 11. 28. 00:00ASPNET/ASPNET 7

반응형

output caching 은 어떠한 입력에 대해 output 되는 값을 caching 해 놓고

특정 시간동안 caching 값을 사용하도록 하는 것이다. 

 

ASPNET core web api 프로젝트를 만들고

 

다음 코드를 추가하자

Program.cs

...
builder.Services.AddOutputCache();
...
app.UseOutputCache();
...

 

Controller 를 사용하게 project 를 만들었을 경우

 

처음 생성 했을때 있는  weatherforecast 관련 코드들을 전부 삭제 하자

 

CacheController.cs 를 추가하자.

그리고 다음과 같이 코드를 수정하자.

 

 

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OutputCaching;

namespace OutputCache.Controllers;
[ApiController]
[Route("[controller]")]
public class CacheController : ControllerBase
{
    private readonly ILogger<CacheController> _logger;

    public CacheController(ILogger<CacheController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [OutputCache(Duration = 10)] // 10 초 동안 caching 하여 같은 값을 보여준다.
    public string Get() => $"Hello!! {DateTime.Now.Ticks}";
    
}

실행후 swagger 에서 해당 함수를 실행해 보자

 

10초 동안 같은 내용이 찍히는 것을 알 수 있다. 

 

10초가 지나면 값이 변경된다. 

 

 

 

Controller 단위의 Caching 도 가능하다

// controller 상단에 OutputCache attribute 사용하여
// controller 전체에 적용 가능하다.
[OutputCache(Duration = 5)]
public class CacheController : ControllerBase
...

 

 

기본 caching 정책 

  • HTTP 200 응답만 캐시된다.
  • HTTP GET 또는 HEAD 요청만 캐시된다.
  • cookie를 설정한 응답은 캐시되지 않는다.
  • 인증된 요청에 대한 응답은 캐시되지 않는다.

 

만약 모든 Controller 및 API 에 caching 을 적용하려면 아래와 같이 한다. 

builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(builder => builder.Cache());
});

 

필요한 것에 직접 Caching 을 적용 하고 싶다면  아래와 같이 한다. 

builder.Services.AddOutputCache();

이후 필요한 api 나 controller 에 [OutputCache] 속성이나 CacheOutput() method 를 사용한다. 

 

 

Caching Delete

 

만약 caching 을 delete (refresh) 해서 실제 data 를 가지고 오고 싶다면 tag 를 활용하여야 한다. 

 

...
builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(builder => builder
        .With(c => c.HttpContext.Request.Path.StartsWithSegments("/cache"))
        .Tag("tag-cache"));    
});
...

 

Tag 에 해당하는 caching 을 삭제하기 위해 다음 코드를 사용한다. 

[HttpDelete("delete")]
public async ValueTask RefreshCache([FromServices]IOutputCacheStore cache, string tag)
{
    await cache.EvictByTagAsync(tag, default);
}

 

위를 delete 에 "tag-cache" 를 실행하면

Tag 를 설정한 api 는 caching 이 delete(refresh) 된다. (새 값을 가져옴)

나머지는 cache 규칙을 그대로 따른다. (caching 됨)

 

Caching Policy

Caching Policy 를 설정하여 expire time 이나 no cache 등을 설정 가능 하다.

 

builder.Services.AddOutputCache(options =>
{
    ...
    options.AddPolicy("Expire30", builder => builder.Expire(TimeSpan.FromSeconds(30)));
    options.AddPolicy("NoCache", builder => builder.NoCache());
    ...
});

Controller 에서 다음 코딩

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OutputCaching;

namespace OutputCache.Controllers;
[ApiController]
[Route("[controller]")]
[OutputCache(Duration = 10)]

public class CacheController : ControllerBase
{
    ...
    [HttpGet("policy")]
    [OutputCache(PolicyName ="Expire30")] // 30초 후에 caching refresh
    public string GetWithPolicy() => $"Hello!! {DateTime.Now.Ticks}";

    [HttpGet("nocache")]
    [OutputCache(PolicyName = "NoCache")] // caching 하지 않음
    public string GetWithNoCache() => $"Hello!! {DateTime.Now.Ticks}";
	...
}

 

 

Minimal API 를 이용하여 project 를 만들었을 경우

var cache = app.MapGroup("/minimal/cache"); //controller 처럼 grouping 가능
cache.CacheOutput(builder => builder.Tag("tag-minimal-cache")); // 해당 group 에 tag 설정

cache.MapGet("/", () =>
{
    return $"Hello!! {DateTime.Now.Ticks}";
}); // 기본 caching time (1분 후 expire)

cache.MapGet("/{id}", (string id) =>
{
    return $"Hello!! {DateTime.Now.Ticks}";
}).CacheOutput("Expire30"); // 30초후 expiration

cache.MapGet("/nocache", () =>
{
    return $"Hello!! {DateTime.Now.Ticks}";
})
.WithName("NoCache")  
.CacheOutput("NoCache"); // policy 를 주어서 no chache 처리

 

** 사용해 보며 느낀점은 Minimal API 쪽에 좀더 신경을 쓴것 같다. 

Controller 쪽에서는 Tag 에 해당하는 attribute 가 없는 관계로 해당 값을 처리 할 수 없었고

아래와 같은 코드로 대체해야 했다.

options.AddBasePolicy(builder => builder
        .With(c => c.HttpContext.Request.Path.StartsWithSegments("/cache"))
        .Tag("tag-cache"));

이전에 Minimal API 가 단순하지만 지원되지 않는 부분이 많아 불편 했다면

향후 버전들은 오히려 Minimal API 가 더 많은 지원을 할 것 같은 기분이 든다. **

 

관련영상

https://youtu.be/V8MMKEoBia4

반응형

'ASPNET > ASPNET 7' 카테고리의 다른 글

gRPC HealthCheck  (0) 2022.12.15
ASPNET 7 - Endpoint Filter  (0) 2022.12.12
ASPNET 7 - Authentication  (0) 2022.12.08
ASPNET 7 - Route Group and Swagger  (0) 2022.12.05
ASPNET 7 - Rate Limit  (0) 2022.12.01