aboutsummaryrefslogtreecommitdiff
path: root/README.org
blob: 28f52822e89a1c8e834c77864260146d96463c99 (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
102
103
104
* What

~lazybones~ is a small HTTP routing framework.

Features include: 

- Different server backends. (At the moment only Hunchentoot is supported)
- Modular and "installable" applications.
- Handy macros for provisioning apps and defining endpoints.
- In particular, strings representing endpoint paths may contain
  variables and include parsers and validators for variables
- Query parameters may also be parsed and validated with a simple syntax
- Customizable errors.
- Livecoding supported for your endpoint handlers and application configurations.
- Automatic documentation generation for ~lazybones:app~ instances.
- Automatic generation of API client code for Lisp and Javascript

Although lazybones can be used to develop and serve page-oriented web
sites, it has been written to help me develop "self documenting" HTTP
APIs.

** Main Components 

The main components in ~lazybones~ are the two classes: ~lazybones:app~
and ~lazybones:endpoint~.  

Endpoints are objects that represent everything required to handle an
HTTP request.  Endpoints are collected into groups called apps.  

Apps, in addition to being collections of endpoints, are the main unit
of development for larger lazybones projects. Apps can be installed to
running servers on the fly as whole units. If desired, they can also
be uninstalled.  Apps are meant to be devolped in a
one-app-per-package manner.  That is, although you can create and work
with multiple apps in a single Common Lisp package, ~lazybones~
encourages you to limit yourself to one per package.  

See the example below for more.

** A Hello World Example 

#+begin_src lisp

(asdf:load-system "lazybones-hunchentoot")

(defpackage #:hello-lazybones
  (:use #:cl)
  (:local-nicknames (#:lzb #:lazybones))
  (:import-from #:lazybones #:defendpoint* #:http-ok))

(in-package :hello-lazybones)

(defendpoint* :get "/hello/:name:" () ()
  "Responds with a greeting to NAME" 
  (format nil "Welcome to Lazybones, ~a" name))

(defvar *my-server* (lzb:create-server))
(lzb:install-app *my-server* (lzb:app))
(lzb:start-server *my-server*)
#+end_src


Go ahead and test this sever out with curl:

#+begin_src shell
$ curl -v http://localhost:8888/hello/colin
Trying 127.0.0.1:8888...
Connected to localhost (127.0.0.1) port 8888 (#0)
> GET /hello/colin HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.74.0
> Accept: */*
> 
Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 27
< Date: Wed, 09 Feb 2022 12:26:01 GMT
< Server: Hunchentoot 1.3.0
< Content-Type: text/html; charset=utf-8
< 
Connection #0 to host localhost left intact
Welcome to Lazybones, colin
#+end_src

Check the ~example~ directory in this repository for a more elaborate example. 

** Documentation Generation 

You can generate Markdown documentation for an instance of
~layzbones:app~ using ~lazybones:generate-app-documentation~.  For an
example API and example documentation, see the ~example~ directory in
this repository.

** Backends 

**WARNING** Users can mostly ignore thissection. The API for alternate backends is in
flux.

To implement a new backend for lazybones, consult the
~lazybones.backend~ package. Define a new system and a new package
that ~uses~ the lazybones.backend package. Implement functions for
each symbol.  Consult the ~lazybones-hunchentoot~ system for an
example backend.