I want to understand how to control when responses are 'cached' versus when they are 'recalculated'.
As an example:
[<EntryPoint>]
let main [| port |] =
let config =
{ defaultConfig with
bindings = [ HttpBinding.mk HTTP IPAddress.Loopback (uint16 port) ]
listenTimeout = TimeSpan.FromMilliseconds 3000.
}
let appDemo:WebPart =
DateTime.Now.ToString()
|> sprintf "Server timestamp: %s"
|> Successful.OK
startWebServer config appDemo
If I run the above webserver and hit it several times then each time I get the same timestamp back. Which I guess makes sense; appDemo
is just an expression which is calculated first time around and never again, right?
In this circumstance, I might want appDemo
to be 'recalculated' for every request. How do I do that? I can't seem to find an example in the docs.
There are two main HTTP response headers that we can use to control caching behavior: The Expires HTTP header specifies an absolute expiry time for a cached representation. Beyond that time, a cached representation is considered stale and must be re-validated with the origin server.
Response caching reduces the number of requests a client or proxy makes to a web server. Response caching also reduces the amount of work the web server performs to generate a response. Response caching is controlled by headers that specify how you want client, proxy, and middleware to cache responses.
The ResponseCache attribute participates in setting response caching headers. Clients and intermediate proxies should honor the headers for caching responses under the HTTP 1.1 Caching specification. For server-side caching that follows the HTTP 1.1 Caching specification, use Response Caching Middleware.
It is not stored in shared cache. To make it private, we need to specify "Location = ResponseCacheLocation.Client" along with ResponseCachen attribute. The "no-cache" request directive indicates that cache has not stored any part of either response or request.
Try this - not sure how high it scores on "idiomatic Suave" scale though:
let appDemo:WebPart =
request (fun req ->
DateTime.Now.ToString()
|> sprintf "Server timestamp: %s"
|> Successful.OK)
You're right in that you're seeing the same value because it's captured at the time appDemo is evaluated. That's a property of how F# works however, and has nothing to do with Suave caching it.
Note that WebPart
type is an alias for HttpContext -> Async<HttpContext option>
function - so inherently it yields itself to being recalculated on each request rather than being calculated once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With