From b39e004d48bccffcc83843b2ee4e1ebdc5cf489a Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 11 May 2024 13:31:47 -0700 Subject: Add: readme discussion about route defining --- README.org | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/README.org b/README.org index 940f192..6321006 100644 --- a/README.org +++ b/README.org @@ -56,3 +56,85 @@ OOPyness is an advantage. Object orientation allows one to: - Similarly, you can automatically generate API client code for your langauge of choice. + +** Defining Routes + +All routes are defined by supplying route parts. + +Each route part is a string and these strings are combined into a +regular expression. + +Match groups inside the regular expression are extracted and parsed +according to the value of the ~:extractors~ slot. + +If there are N match groups in a route, then there must be N extractors. + +E.g + +#+begin_src lisp +(defclass example () + ((foo-id + :type integer + :reader foo-id + :initarg :foo-id) + (bar-val + :type string + :reader bar-val + :initarg :bar-val)) + (:metaclass weekend:endpoint) + (:method . :get) + (:route-groups "foo" "([0-9]+)" "bar" "(blah|nah)") + (:extractors (:foo-id parse-integer) :bar-val)) + +#+end_src + + +In ~:route-groups~ there are four parts, two match groups, and two +extractors. + +The parts will be combined into a regular expression: +="^/foo/([0-9]+)/bar/(blah|nah)$"= + +The first match group matches a string of digits. That string is +parsed by ~parse-integer~ and then supplied to the ~:foo-id~ initarg. + +The second match group matches either ~"blah"~ or ~"nah"~ and is +passed as-is tot he ~:bar-val~ initarg. + +This class would handle the route =GET /foo/322/bar/nah= for example. + +You might be asking yourself "why not just write the regex as a +string?" Well thats a good question. You can actually do that (dig +into the ~endpoint~ metaclass yourself to see how), but the reason I +prefer ~:route-parts~ is to allow for defining your regex pattern +groups outside of the route as module parameters. See +examples/dice-roller.lisp. + +** Passing Values in Query Params + +Here we modify the above example by only passing one argument in the +route, leaving the other to be a query parameter. + +#+begin_src lisp +(defclass example2 () + ((foo-id + :type integer + :reader foo-id + :initarg :foo-id) + (bar-val + :type string + :reader bar-val + :initarg :bar-val + :initform (weekend:slot-required 'bar-val 'example2)) + (:metaclass weekend:endpoint) + (:method . :get) + (:route-groups "foo" "([0-9]+)" "bar") + (:extractors (:foo-id parse-integer))) + +#+end_src + +This would handle routes like =GET /foo/323/bar?bar-val=moo= + +If ~bar-val~ had not been supplied in the query parameters, the +~slot-required~ error would be signalled and the client would receive +a 400 HTTP response code. -- cgit v1.2.3