Implement on-demand cache revalidation
This commit is contained in:
parent
ea91a6043e
commit
4532ab3afe
9 changed files with 98 additions and 26 deletions
|
@ -2,5 +2,6 @@ WEBSITE_ENV=
|
|||
WEBSITE_URL=
|
||||
MICROCMS_SERVICE_DOMAIN=
|
||||
MICROCMS_API_KEY=
|
||||
MICROCMS_WEBHOOK_KEY=
|
||||
CLOUDFLARE_ZONE_ID=
|
||||
CLOUDFLARE_API_KEY=
|
||||
|
|
2
qlfile
2
qlfile
|
@ -9,3 +9,5 @@ ql clack-errors
|
|||
git microcms https://github.com/skyizwhite/microcms-lisp-sdk
|
||||
ql local-time
|
||||
ql function-cache
|
||||
ql jonathan
|
||||
ql flexi-streams
|
||||
|
|
|
@ -46,3 +46,11 @@
|
|||
(:class qlot/source/ql:source-ql
|
||||
:initargs (:%version :latest)
|
||||
:version "ql-2023-10-21"))
|
||||
("jonathan" .
|
||||
(:class qlot/source/ql:source-ql
|
||||
:initargs (:%version :latest)
|
||||
:version "ql-2020-09-25"))
|
||||
("flexi-streams" .
|
||||
(:class qlot/source/ql:source-ql
|
||||
:initargs (:%version :latest)
|
||||
:version "ql-2024-10-12"))
|
||||
|
|
26
src/helper.lisp
Normal file
26
src/helper.lisp
Normal file
|
@ -0,0 +1,26 @@
|
|||
(uiop:define-package #:website/helper
|
||||
(:use #:cl
|
||||
#:jingle)
|
||||
(:import-from #:flexi-streams
|
||||
#:make-flexi-stream)
|
||||
(:import-from #:jonathan
|
||||
#:parse)
|
||||
(:export #:api-request-p
|
||||
#:get-request-body-plist))
|
||||
(in-package #:website/helper)
|
||||
|
||||
(defun starts-with-p (prefix string)
|
||||
(let ((pos (search prefix string :start1 0 :end1 (length prefix) :start2 0)))
|
||||
(and pos (= pos 0))))
|
||||
|
||||
(defun api-request-p ()
|
||||
(starts-with-p "/api/" (request-uri *request*)))
|
||||
|
||||
(defun get-request-body-plist ()
|
||||
(parse
|
||||
(let ((text-stream (make-flexi-stream (request-raw-body *request*)
|
||||
:external-format :utf-8)))
|
||||
(with-output-to-string (out)
|
||||
(loop :for char := (read-char text-stream nil)
|
||||
:while char
|
||||
:do (write-char char out))))))
|
|
@ -17,19 +17,19 @@
|
|||
(setf microcms:*service-domain* (microcms-service-domain))
|
||||
(setf microcms:*api-key* (microcms-api-key))
|
||||
|
||||
(defmacro memorize (name timeout)
|
||||
(defmacro memorize (name)
|
||||
(let ((origin (gensym)))
|
||||
`(progn
|
||||
(setf (fdefinition ',origin) (fdefinition ',name))
|
||||
(defcached (,name :timeout ,timeout) (&key query)
|
||||
(defcached ,name (&key query)
|
||||
(,origin :query query)))))
|
||||
|
||||
(define-object-client about)
|
||||
(memorize get-about 60)
|
||||
(memorize get-about)
|
||||
|
||||
(define-object-client work)
|
||||
(memorize get-work 60)
|
||||
(memorize get-work)
|
||||
|
||||
(define-list-client blog)
|
||||
(memorize get-blog-list 60)
|
||||
(memorize get-blog-detail 60)
|
||||
(memorize get-blog-list)
|
||||
(memorize get-blog-detail)
|
||||
|
|
|
@ -18,3 +18,4 @@
|
|||
(env-var website-url "WEBSITE_URL")
|
||||
(env-var microcms-service-domain "MICROCMS_SERVICE_DOMAIN")
|
||||
(env-var microcms-api-key "MICROCMS_API_KEY")
|
||||
(env-var microcms-webhook-key "MICROCMS_WEBHOOK_KEY")
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
(:use #:cl
|
||||
#:hsx
|
||||
#:jingle)
|
||||
(:import-from #:hsx/element
|
||||
#:element)
|
||||
(:import-from #:jonathan
|
||||
#:to-json)
|
||||
(:import-from #:website/helper
|
||||
#:api-request-p)
|
||||
(:import-from #:website/components/metadata
|
||||
#:~metadata)
|
||||
(:import-from #:website/components/scripts
|
||||
|
@ -13,17 +15,21 @@
|
|||
(in-package #:website/renderer)
|
||||
|
||||
(defmethod jingle:process-response :around ((app jingle:app) result)
|
||||
(set-response-header :content-type "text/html; charset=utf-8")
|
||||
(when (eq (request-method *request*) :get)
|
||||
(set-response-header :cache-control "public, max-age=60"))
|
||||
(call-next-method app
|
||||
(render-to-string
|
||||
(hsx (html :lang "ja"
|
||||
(head
|
||||
(~metadata :metadata (context :metadata))
|
||||
(~scripts))
|
||||
(body
|
||||
:hx-ext "head-support, response-targets, preload"
|
||||
:hx-boost "true" :hx-swap "transition:true"
|
||||
:hx-target-404 "body" :hx-target-5* "body"
|
||||
(~layout result)))))))
|
||||
(cond ((api-request-p)
|
||||
(set-response-header :content-type "application/json; charset=utf-8")
|
||||
(call-next-method app (to-json result)))
|
||||
(t
|
||||
(set-response-header :content-type "text/html; charset=utf-8")
|
||||
(call-next-method app
|
||||
(render-to-string
|
||||
(hsx (html :lang "ja"
|
||||
(head
|
||||
(~metadata :metadata (context :metadata))
|
||||
(~scripts))
|
||||
(body
|
||||
:hx-ext "head-support, response-targets, preload"
|
||||
:hx-boost "true" :hx-swap "transition:true"
|
||||
:hx-target-404 "body" :hx-target-5* "body"
|
||||
(~layout result)))))))))
|
||||
|
|
24
src/routes/api/revalidate.lisp
Normal file
24
src/routes/api/revalidate.lisp
Normal file
|
@ -0,0 +1,24 @@
|
|||
(defpackage #:website/routes/api/revalidate
|
||||
(:use #:cl
|
||||
#:jingle)
|
||||
(:import-from #:function-cache
|
||||
#:clear-cache)
|
||||
(:import-from #:website/lib/env
|
||||
#:microcms-webhook-key)
|
||||
(:import-from #:website/helper
|
||||
#:get-request-body-plist)
|
||||
(:import-from #:website/lib/cms
|
||||
#:get-about)
|
||||
(:export #:handle-post))
|
||||
(in-package #:website/routes/api/revalidate)
|
||||
|
||||
(defun handle-post (params)
|
||||
(declare (ignore params))
|
||||
(unless (string= (car (get-request-header "X-MICROCMS-WEBHOOK-KEY"))
|
||||
(microcms-webhook-key))
|
||||
(set-response-status :unauthorized)
|
||||
(return-from handle-post '(:|message| "Invalid token")))
|
||||
(let* ((body (get-request-body-plist))
|
||||
(api (getf body :|api|)))
|
||||
(cond ((string= api "about") (clear-cache 'get-about)))
|
||||
'(:|message| "ok")))
|
|
@ -2,6 +2,8 @@
|
|||
(:use #:cl
|
||||
#:hsx
|
||||
#:jingle)
|
||||
(:import-from #:website/helper
|
||||
#:api-request-p)
|
||||
(:export #:handle-not-found))
|
||||
(in-package #:website/routes/not-found)
|
||||
|
||||
|
@ -12,9 +14,11 @@
|
|||
|
||||
(defun handle-not-found ()
|
||||
(setf (context :metadata) *metadata*)
|
||||
(hsx
|
||||
(div :class "flex flex-col h-full items-center justify-center gap-y-6"
|
||||
(h1 :class "font-bold text-2xl"
|
||||
"404 Not Found")
|
||||
(a :href "/" :class "text-lg text-pink-500 hover:underline"
|
||||
"Back to TOP"))))
|
||||
(if (api-request-p)
|
||||
'(:|message| "404 Not Found")
|
||||
(hsx
|
||||
(div :class "flex flex-col h-full items-center justify-center gap-y-6"
|
||||
(h1 :class "font-bold text-2xl"
|
||||
"404 Not Found")
|
||||
(a :href "/" :class "text-lg text-pink-500 hover:underline"
|
||||
"Back to TOP")))))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue