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=
|
WEBSITE_URL=
|
||||||
MICROCMS_SERVICE_DOMAIN=
|
MICROCMS_SERVICE_DOMAIN=
|
||||||
MICROCMS_API_KEY=
|
MICROCMS_API_KEY=
|
||||||
|
MICROCMS_WEBHOOK_KEY=
|
||||||
CLOUDFLARE_ZONE_ID=
|
CLOUDFLARE_ZONE_ID=
|
||||||
CLOUDFLARE_API_KEY=
|
CLOUDFLARE_API_KEY=
|
||||||
|
|
2
qlfile
2
qlfile
|
@ -9,3 +9,5 @@ ql clack-errors
|
||||||
git microcms https://github.com/skyizwhite/microcms-lisp-sdk
|
git microcms https://github.com/skyizwhite/microcms-lisp-sdk
|
||||||
ql local-time
|
ql local-time
|
||||||
ql function-cache
|
ql function-cache
|
||||||
|
ql jonathan
|
||||||
|
ql flexi-streams
|
||||||
|
|
|
@ -46,3 +46,11 @@
|
||||||
(:class qlot/source/ql:source-ql
|
(:class qlot/source/ql:source-ql
|
||||||
:initargs (:%version :latest)
|
:initargs (:%version :latest)
|
||||||
:version "ql-2023-10-21"))
|
: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:*service-domain* (microcms-service-domain))
|
||||||
(setf microcms:*api-key* (microcms-api-key))
|
(setf microcms:*api-key* (microcms-api-key))
|
||||||
|
|
||||||
(defmacro memorize (name timeout)
|
(defmacro memorize (name)
|
||||||
(let ((origin (gensym)))
|
(let ((origin (gensym)))
|
||||||
`(progn
|
`(progn
|
||||||
(setf (fdefinition ',origin) (fdefinition ',name))
|
(setf (fdefinition ',origin) (fdefinition ',name))
|
||||||
(defcached (,name :timeout ,timeout) (&key query)
|
(defcached ,name (&key query)
|
||||||
(,origin :query query)))))
|
(,origin :query query)))))
|
||||||
|
|
||||||
(define-object-client about)
|
(define-object-client about)
|
||||||
(memorize get-about 60)
|
(memorize get-about)
|
||||||
|
|
||||||
(define-object-client work)
|
(define-object-client work)
|
||||||
(memorize get-work 60)
|
(memorize get-work)
|
||||||
|
|
||||||
(define-list-client blog)
|
(define-list-client blog)
|
||||||
(memorize get-blog-list 60)
|
(memorize get-blog-list)
|
||||||
(memorize get-blog-detail 60)
|
(memorize get-blog-detail)
|
||||||
|
|
|
@ -18,3 +18,4 @@
|
||||||
(env-var website-url "WEBSITE_URL")
|
(env-var website-url "WEBSITE_URL")
|
||||||
(env-var microcms-service-domain "MICROCMS_SERVICE_DOMAIN")
|
(env-var microcms-service-domain "MICROCMS_SERVICE_DOMAIN")
|
||||||
(env-var microcms-api-key "MICROCMS_API_KEY")
|
(env-var microcms-api-key "MICROCMS_API_KEY")
|
||||||
|
(env-var microcms-webhook-key "MICROCMS_WEBHOOK_KEY")
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
(:use #:cl
|
(:use #:cl
|
||||||
#:hsx
|
#:hsx
|
||||||
#:jingle)
|
#:jingle)
|
||||||
(:import-from #:hsx/element
|
(:import-from #:jonathan
|
||||||
#:element)
|
#:to-json)
|
||||||
|
(:import-from #:website/helper
|
||||||
|
#:api-request-p)
|
||||||
(:import-from #:website/components/metadata
|
(:import-from #:website/components/metadata
|
||||||
#:~metadata)
|
#:~metadata)
|
||||||
(:import-from #:website/components/scripts
|
(:import-from #:website/components/scripts
|
||||||
|
@ -13,17 +15,21 @@
|
||||||
(in-package #:website/renderer)
|
(in-package #:website/renderer)
|
||||||
|
|
||||||
(defmethod jingle:process-response :around ((app jingle:app) result)
|
(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)
|
(when (eq (request-method *request*) :get)
|
||||||
(set-response-header :cache-control "public, max-age=60"))
|
(set-response-header :cache-control "public, max-age=60"))
|
||||||
(call-next-method app
|
(cond ((api-request-p)
|
||||||
(render-to-string
|
(set-response-header :content-type "application/json; charset=utf-8")
|
||||||
(hsx (html :lang "ja"
|
(call-next-method app (to-json result)))
|
||||||
(head
|
(t
|
||||||
(~metadata :metadata (context :metadata))
|
(set-response-header :content-type "text/html; charset=utf-8")
|
||||||
(~scripts))
|
(call-next-method app
|
||||||
(body
|
(render-to-string
|
||||||
:hx-ext "head-support, response-targets, preload"
|
(hsx (html :lang "ja"
|
||||||
:hx-boost "true" :hx-swap "transition:true"
|
(head
|
||||||
:hx-target-404 "body" :hx-target-5* "body"
|
(~metadata :metadata (context :metadata))
|
||||||
(~layout result)))))))
|
(~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
|
(:use #:cl
|
||||||
#:hsx
|
#:hsx
|
||||||
#:jingle)
|
#:jingle)
|
||||||
|
(:import-from #:website/helper
|
||||||
|
#:api-request-p)
|
||||||
(:export #:handle-not-found))
|
(:export #:handle-not-found))
|
||||||
(in-package #:website/routes/not-found)
|
(in-package #:website/routes/not-found)
|
||||||
|
|
||||||
|
@ -12,9 +14,11 @@
|
||||||
|
|
||||||
(defun handle-not-found ()
|
(defun handle-not-found ()
|
||||||
(setf (context :metadata) *metadata*)
|
(setf (context :metadata) *metadata*)
|
||||||
(hsx
|
(if (api-request-p)
|
||||||
(div :class "flex flex-col h-full items-center justify-center gap-y-6"
|
'(:|message| "404 Not Found")
|
||||||
(h1 :class "font-bold text-2xl"
|
(hsx
|
||||||
"404 Not Found")
|
(div :class "flex flex-col h-full items-center justify-center gap-y-6"
|
||||||
(a :href "/" :class "text-lg text-pink-500 hover:underline"
|
(h1 :class "font-bold text-2xl"
|
||||||
"Back to TOP"))))
|
"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