aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <okay@toyful.space>2022-02-13 19:38:51 -0600
committerColin Okay <okay@toyful.space>2022-02-13 19:38:51 -0600
commit49f8cafff4b63ebb7c0fa3bfc182072d8d5197ea (patch)
tree69f071f9bffad05bf3f8cea8098d424a4d70fedc
parent74eda585255b4a4d26cc783cecf2312a71370ed3 (diff)
Made 200 response the default. http-err now singals condition
-rw-r--r--example/lazybones-example.lisp21
-rw-r--r--lazybones-hunchentoot.lisp9
-rw-r--r--lazybones.asd2
-rw-r--r--lazybones.lisp22
-rw-r--r--package.lisp2
5 files changed, 27 insertions, 29 deletions
diff --git a/example/lazybones-example.lisp b/example/lazybones-example.lisp
index 1efc882..88a58a1 100644
--- a/example/lazybones-example.lisp
+++ b/example/lazybones-example.lisp
@@ -5,7 +5,6 @@
(:local-nicknames (#:lzb #:lazybones))
(:import-from #:lazybones
#:defendpoint*
- #:http-ok
#:http-err))
(in-package :lazybones-example)
@@ -60,21 +59,21 @@
to 'coolsessionbro'."
(print (lzb:request-body)) ; dummy implementation, prints post body to stdout
(setf (lzb:response-cookie "testappsession") "coolsessionbro")
- (http-ok "true"))
+ "true")
;; The next route defines a route variable WHO
(defendpoint* :get "/hello/:who:" () ()
"Echos back Hello WHO"
- (http-ok (format nil "Hello ~a~%" who))) ; use the route variable here
+ (format nil "Hello ~a~%" who)) ; use the route variable here
(defendpoint* :post "/hello/:who:" ()
(:auth t) ; use the app's default authorizor
"Echo's back 'Hello WHO, I got your message BODY' where BODY is the post body."
(print (lzb:request-header :content-type))
(let ((body (lzb:request-body)))
- (http-ok (format nil "Hello ~a, I got your message ~a~%"
- who body))))
+ (format nil "Hello ~a, I got your message ~a~%"
+ who body)))
;; Some helpers, these are used to parse url variables and query
;; parameters. Their docstrings are used in the API documentation
@@ -92,7 +91,7 @@
;; a 500 error will be returned. The syntax is (VAR PARSER)
(defendpoint* :get "/search" ((name str) (age int)) ()
"Echo the search parameters in a nice list."
- (http-ok (format nil "Name: ~a~%age: ~a~%" name age)))
+ (format nil "Name: ~a~%age: ~a~%" name age))
(defun crapshoot-authorizer ()
"Randomly decides that the request is authorized"
@@ -101,16 +100,15 @@
(defendpoint* :post "/crapshoot" ()
(:auth 'crapshoot-authorizer) ; use a custom authorizer
"Echos back 'You made it' if the request was authorized"
- (http-ok "You made it"))
+ "You made it")
;; Route variables can accept parsers / preformatters
;; these will parse a value and supply it to the argument of the handler.
(defendpoint* :get "/random/:lo int:/:hi int:" () ()
"Echo back a random number between lo and hi"
(if (< lo hi)
- (http-ok
- (format nil "The number is: ~a~%"
- (+ lo (random (- hi lo)))))
+ (format nil "The number is: ~a~%"
+ (+ lo (random (- hi lo))))
(http-err 404))) ; Can't find a number X such that LO >= HI and LO < X < HI
(defun person-by-id (id)
@@ -124,6 +122,5 @@
(defendpoint* :get "/person/:person person-by-id:" ()
(:content-type "application/json") ; override the app's default content type for HTTP responses
"Returns a json representation of the person."
- (http-ok
- (jonathan:to-json person)))
+ (jonathan:to-json person))
diff --git a/lazybones-hunchentoot.lisp b/lazybones-hunchentoot.lisp
index b010052..c5e55fa 100644
--- a/lazybones-hunchentoot.lisp
+++ b/lazybones-hunchentoot.lisp
@@ -39,11 +39,16 @@
finally (let ((lzb:*request* request)
(lzb:*response* h:*reply*))
(return (lzb:http-err 404))))
+ (lzb::http-error (http-error)
+ (let ((lzb:*request* request)
+ (lzb:*response* h:*reply*))
+ (with-slots (lzb::code lzb::content) http-error
+ (http-respond lzb::content lzb::code))))
(error (e)
(declare (ignorable e))
(let ((lzb:*request* request)
(lzb:*response* h:*reply*))
- (lzb:http-err 500)))))
+ (http-respond 500)))))
;;; SERVER FUNCTIONS
@@ -220,7 +225,7 @@ the value of the Content-Type request header."
(cadar (setf (h:cookies-out response)
(cons (cons name value) (h:cookies-out response))))))
-(defun http-respond (code content)
+(defun http-respond (content &optional (code 200))
"Final step preparing response before backend does the rest. For
Hunchentoot, set the response code and a few headers. If content is a
pathname, pass off to HUNCHENTOOT:HANDLE-STATIC-FILE, otherwise just
diff --git a/lazybones.asd b/lazybones.asd
index 415b2c1..367c7c2 100644
--- a/lazybones.asd
+++ b/lazybones.asd
@@ -4,7 +4,7 @@
:description "http route handling"
:author "Colin Okay <okay@toyful.space>"
:license "AGPLv3"
- :version "0.3.0"
+ :version "0.4.0"
:serial t
:depends-on (#:alexandria
#:str
diff --git a/lazybones.lisp b/lazybones.lisp
index bab6ca2..fe2ebc3 100644
--- a/lazybones.lisp
+++ b/lazybones.lisp
@@ -18,6 +18,13 @@
"Dynamic variable holding the an APP instance. Dynamically bound by
RUN-ENDPOINT so that it is available if needed in request handlers.")
+;;; HTTP-ERROR CONDITION
+
+(define-condition http-error (condition)
+ ((code :initarg :code)
+ (content :initarg :content)))
+
+
;;; APP NAMESPACE
(lisp-namespace:define-namespace lazybones)
@@ -365,21 +372,10 @@ making a new one if not."
"Like DEFENDPOINT but uses the current package name as the app name."
`(defendpoint ,(default-app-name) ,method ,route ,params ,options ,@body))
-
-
-
;;; ENDPOINT HANDLING UTILITIES
-
-(defun http-ok (content)
- "Content should be a string, a byte-vector, or a pathname to a local
-file. CONTENT-TYPE should be a MIME type string."
- (http-respond 200 content))
-
(defun http-err (code &optional content)
- "*APP*, *RESPONSE* and *REQUEST* should all be defined here."
- (http-respond
- code
- content))
+ "Singals an HTTP-ERROR with code and content."
+ (signal 'http-error :content content :code code))
diff --git a/package.lisp b/package.lisp
index 22766cd..35ef7ab 100644
--- a/package.lisp
+++ b/package.lisp
@@ -41,6 +41,7 @@
#:*app*
#:*request*
#:*response*
+ #:http-error
#:generate-app-documentation
#:provision-app
#:app
@@ -53,7 +54,6 @@
#:let-parameters
#:map-parameters
#:http-err
- #:http-ok
#:http-respond
#:install-app
#:request-body