|
| 1 | + |
| 2 | +## Web apps in Lisp |
| 3 | + |
| 4 | +You want to write a web application in Common Lisp and you don't know |
| 5 | +where to start? Or you don't want to re-invent the wheel? Follow the guide. |
| 6 | + |
| 7 | + |
| 8 | +## Why Common Lisp |
| 9 | + |
| 10 | +For web development as for any other task, one can leverage Common |
| 11 | +Lisp's advantages: |
| 12 | + |
| 13 | +- the **unmatched REPL** that even helps to interact with a running web app on your remote server, |
| 14 | +- the **exception handling system**, |
| 15 | +- **performance**, |
| 16 | +- easy deployment: ability to build **self-contained executables** containing all our static files, |
| 17 | +- **stability**, |
| 18 | +- **good threads story**, |
| 19 | +- **strong** and incremental **typing**, |
| 20 | +- etc. |
| 21 | + |
| 22 | +All the development experience is very much interactive, allowing us |
| 23 | +to write and test features right away. **There are no compile times** |
| 24 | +during development, we only need to compile the app from scratch once in |
| 25 | +a while, to check that our dependencies or the project layout are |
| 26 | +correctly declared. |
| 27 | + |
| 28 | +We can, for example, define a new route and try it right away, **we |
| 29 | +don't wait for a local web server** to pick up the changes and |
| 30 | +restart. In case of an error, the interactive debugger pops up (if we |
| 31 | +want to), **no server will crash because of an undefined variable** |
| 32 | +(looking at you, Python). We can edit a function and compile it with a |
| 33 | +keyboard shortcut (the usual `C-c C-c` in Slime): we can compile our |
| 34 | +code *one function at a time*. The **feedback is |
| 35 | +immediate**. |
| 36 | + |
| 37 | +We can **choose the degree of interactivity**: the web server |
| 38 | +can catch exceptions and fire the interactive debugger, or print lisp |
| 39 | +backtraces on the browser, or display a 404 error page and print logs |
| 40 | +on standard output. The ability to build self-contained executables |
| 41 | +eases deployment tremendously (compared to, for example, npm-based |
| 42 | +apps), in that we just copy the executable to a server and run it. |
| 43 | + |
| 44 | +But we can also run it as a "script" from sources. |
| 45 | + |
| 46 | +In both cases, when we have deployed it, we can still **interact |
| 47 | +with the running application**, allowing for **hot code reload**. We |
| 48 | +can even install new dependencies while it is running, no process has |
| 49 | +to restart. Of course, if we prefer to be careful and we don't want to use live |
| 50 | +reload capabilities, we might still enjoy this capability to reload, for example, |
| 51 | +a user's configuration file. |
| 52 | + |
| 53 | +So Common Lisp can be a good choice for web development too. The |
| 54 | +ecosystem has lots of little or not so little libraries, including a |
| 55 | +production-ready, battle proven web framework (Hunchentoot). |
| 56 | + |
| 57 | +However, **we don't have a batteries-included web framework easily |
| 58 | +usable by novice web developers** (yet…). But now you have this guide. |
| 59 | + |
| 60 | +## What's in this guide |
| 61 | + |
| 62 | +We'll present here some established web frameworks and other common |
| 63 | +libraries to help you getting started in developing a web |
| 64 | +application. We do *not* aim to be exhaustive nor to replace the |
| 65 | +upstream documentation. |
| 66 | + |
| 67 | +We will learn: |
| 68 | + |
| 69 | +- how to start a simple web project with the Hunchentoot web server |
| 70 | + - defining routes |
| 71 | + - returning any content type, including JSON |
| 72 | + - serving HTML |
| 73 | + - HTML will be written in HTML, with a Django-like template engine (Djula), or a more flexible template engine (Ten, but Djula is already very flexible) |
| 74 | + - we will show how to write HTML in s-expressions (with Spinneret) |
| 75 | +- how to connect to a database, how to define models |
| 76 | + - how to serialize and deserialize the models to and from JSON |
| 77 | +- how to debug a running web app |
| 78 | +- how to serve JavaScript |
| 79 | + - how to make AJAX calls to our Lisp backend |
| 80 | + - with pure JavaScript |
| 81 | + - with Vue.js |
| 82 | + - with the ISSR lisp library |
| 83 | + - with the HTMX library |
| 84 | +- how to create user login |
| 85 | +- how to build and deploy a project |
| 86 | + - with executables |
| 87 | + - with SystemD |
| 88 | + - how to configure Nginx |
| 89 | + - how to setup third-party service providers (Sentry, Plausible web analytics, Graphana…) |
| 90 | +- how to set up a Continuous Integration system |
| 91 | +- how to build a Debian package. |
| 92 | + |
| 93 | +Your feedback and contributions are appreciated! |
| 94 | + |
| 95 | +Now let's start with a [frameworks overview](/frameworks). |
| 96 | + |
| 97 | + |
| 98 | +{{% notice note %}} |
| 99 | +🎥 If you need to learn Common Lisp, good news, [I am creating this video course on Udemy](https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358). |
| 100 | +{{% /notice %}} |
| 101 | + |
| 102 | +{{% notice info %}} |
| 103 | + |
| 104 | +If you find similar content from the Cookbook, this is normal. I am the main contributor and I wrote the web page there. This guide wants to be more complete and more advanced. |
| 105 | + |
| 106 | +{{% /notice %}} |
| 107 | + |
| 108 | + |
| 109 | +[hunchentoot]: https://edicl.github.io/hunchentoot |
| 110 | +[clack]: https://github.com/fukamachi/clack |
| 111 | +[caveman]: https://github.com/fukamachi/caveman |
| 112 | +[radiance]: https://github.com/Shirakumo/radiance |
| 113 | +[snooze]: https://github.com/joaotavora/snooze |
| 114 | +[cl-rest-server]: https://github.com/mmontone/cl-rest-server |
| 115 | +[weblocks]: https://github.com/40ants/weblocks |
0 commit comments