aboutsummaryrefslogtreecommitdiff
path: root/examples/defendpoint-examples.lisp
diff options
context:
space:
mode:
authorcolin <colin@cicadas.surf>2024-05-12 09:53:55 -0700
committercolin <colin@cicadas.surf>2024-05-12 09:53:55 -0700
commit5cce96a68272bab5204b806116be98bee051a97d (patch)
tree09d1d4dfba1138b477f0125ec053de5626973700 /examples/defendpoint-examples.lisp
parentce69e1b3c4846b17ca10406e2e7e08d9b46fc7ec (diff)
Add: defendpoint example; Fix: tweak defendpoint docstring
Diffstat (limited to 'examples/defendpoint-examples.lisp')
-rw-r--r--examples/defendpoint-examples.lisp73
1 files changed, 73 insertions, 0 deletions
diff --git a/examples/defendpoint-examples.lisp b/examples/defendpoint-examples.lisp
new file mode 100644
index 0000000..a59d09d
--- /dev/null
+++ b/examples/defendpoint-examples.lisp
@@ -0,0 +1,73 @@
+(defpackage #:weekend.examples.defendpoint
+ (:use #:cl #:weekend)
+ (:import-from #:flatbind #:do>))
+
+(in-package :weekend.examples.defendpoint)
+
+;;; The DICE ROLLER example, but this time with DEFENDPOINT:
+(defparameter +digits+ "([0-9]+)")
+
+(defendpoint roller
+ :get :route "roll" (:rolls +digits+ parse-integer) "d" (:sides +digits+ parse-integer)
+ :returns "text/plain"
+ :parameters
+ (sides integer "The number of sides the die being rolled has.")
+ (rolls integer "The number of times to roll the die.")
+ :documentation "Roll a SIDES-sided die ROLLS times, and announce the total."
+ :handle (format nil "~ad~a = ~a"
+ rolls sides
+ (loop :repeat rolls :sum (1+ (random sides)))))
+
+
+;;; EXAMPLE WITH MULTIPLE INTERACTING ENDPOINTS, AND A MIX-IN FOR
+;;; AUTHENTICATION
+
+;; Serves a form used to identify a user
+(defendpoint who-are-you
+ :get :route "who-are-you"
+ :returns "text/html;charset=utf-8"
+ :documentation "A form to identify yourself"
+ :handle (with-output-to-string (*standard-output*)
+ (princ "<html><head></head><body>")
+ (princ "<form method='POST' action='/my-name-is'>")
+ (princ "<input name='name' placeholder='Your Name'/>")
+ (princ "<button type=submit>Go!</button>")
+ (princ "</form></body></html>")))
+
+;;; A mixin meant to grab the name from a cookie, used to authenticate
+;;; all requests that need to have identified a user.
+;;; If authentication fails, redirects to who-are-you.
+(defclass identified ()
+ ((name :accessor name :type string)))
+
+(defmethod authenticate ((req identified))
+ (or
+ (do>
+ name :when= (get-cookie "weekend-eg-name")
+ :when (and (stringp name) (plusp (length name)))
+ (setf (name req) name))
+ (endpoint-redirect 'who-are-you)))
+
+
+;;; Endpoint that extends IDENTIFIED and just greets the identified.
+(defendpoint you-seem-to-be
+ :using identified
+ :get :route "you-seem-to-be"
+ :returns "text/html;charset=utf-8"
+ :documentation "Just says hello to an identified uesr"
+ :handle (with-output-to-string (*standard-output*)
+ (princ "<html><head></head><body>")
+ (princ "<p>You seem to be ")
+ (princ name) ; INHERITED FROM IDENTIFIED
+ (princ ".</p></body></html>")))
+
+
+;;; POST endpoint that handles setting the name cookie
+(defendpoint my-name-is
+ :post :to "my-name-is"
+ :parameters
+ (name string "The name supplied by the user")
+ :documentation "Set cookie for client's identity."
+ :handle (progn
+ (set-cookie "weekend-eg-name" :value name)
+ (endpoint-redirect 'you-seem-to-be)))