aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 37e9439474d22d48e2d82d003c3a815e52b4d668 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# What

`lazybones` is a half-hearted effort at a small HTTP route handling
framework for smallish dynamic sites, preferably those whose state
lives in the lisp process.

It is not at all 'field tested', does not compete with more thorougly
conceived frameworks, and is itself just a kind of wrapper around
clack.

# Basic Example

``` lisp
(defpackage #:hello-site
  (:use #:cl)
  (import-from #:lazybones
               #:defroute 
               #:http-ok
               #:http-err)
  (import-from #:fictitious-image-db-package
               #:get-image-ids
               #:lookup-image
               #:image-mimetype
               #:image-data))
               
(in-package :hello-site)

(defroute :get "/hello"
  (http-ok "text/html"
    (spinneret:with-html-string
      (:doctype)
      (:html :lang "en"
        (:head 
          (:meta :charset "utf-8")
          (:title "some images"))
        (:body 
          (:h1 "Hello")
          (:ul
              (dolist (img-id (get-image-ids))  ; assuming some function to get ids
                (:li (:img :src (format nil "/image/~a" img-id))))))))))
            
(defroute :get "/image/:id"
  (alexandria:if-let (found (lookup-image id)) ; assuming a funciton to lookup images
    (http-ok (image-mimetype found)            ; and to query properties
             (image-data found))               ; a byte vector
    (http-err 404 "Not Found")))
    

(start :port 5000) ; start the server 

```

Example code that would serve a page containing a list of images.

## Helpful Features

Inside of any handler there is a dynamically bound variable `*req*`
that holds the HTTP request being processed.

Using a form called `with-handler-preamble`, groups of handlers can be
defined that all perform some initialization / access control steps.

For example:

``` lisp

(with-handler-preamble 
    ((unless (authorized-request *req*)
       (http-err 401 "Unauthorized"))

     (make-database-connection))
  
  (defroute :post "/image/:id/edit" 
    ;; ... handle image post ...
    )

  (defroute :delete "/image/:id"
     ;; ... handle image delete ...
     ))

```
# Installation

If you insist on trying `lazybones` for yourself, you'll need to
ensure that your quicklisp can find 

- [parzival](https://github.com/cbeo/parzival) parser framework, for decoding request bodies
- [replay-streams](https://github.com/cbeo/replay-streams) a dependency of parzival 


The easiest approach is probably something like:

    cd ~/quicklisp/local-projects/ 
    git clone https://github.com/cbeo/parzival 
    git clone https://github.com/cbeo/replay-streams 
    git clone https://github.com/cbeo/lazybones
    
With those packages available to quicklisp, you should be able to do
`(ql:quickload :lazybones)` in your REPL.