A few months ago, I decided that lucerne had enough things missing that I was rewriting for different projects, that I would bite the bullet and try writing my own framework. I'm generally a fan of Fernando Borretti's work, and I definitely suggest looking at the different libraries he's created for common lisp webapps, but these days he's been more of an inspiration for writing my own versions than anything else.

So, I've been writing nest for a while, now, which doesn't have much documentation and very spotty test coverage, at the moment, because it is still very much in the process of spilling out of my forehead, like some halting Athena, and I wouldn't want to break anyone else's webapps while I work on it. (I am trying to version and tag it, though, so at least you'll get the same sort of broken if you stick to a tag.)

I was looking through fossdroid.com, yesterday, and noticed the shopping list app, which boasted an open source php and mysql backend. It comes with some script to set it up under apache, but the list of technologies I wasn't very familiar with was too long, so I decided to test out my framework to get it running under lisp (and whatever database you want that's supported by cl-dbi).

Happily, I didn't bite off more than I could chew on this one, and I had it all working by midnight so I could sleep, too!

I found the api very strange, because it's all implemented at one endpoint. The android app also adds a trailing slash to whatever you configure as the host, which was odd, because I would get requests to /api.php/ or // depending on how I configured it. The app sends what function it wants to run as a post parameter, and then, hopefully, all the parameters appropriate for that function are along for the ride, too. It was a good excuse to pull out my validation library for a ride, which I generally use with a macro like

(defmacro validated (&body body)
  "Handle validation errors (`v:<validation-error>`) and respond with an error for the client."

`(handler-case (progn ,@body) (v:<validation-error> (e) (declare (ignore e)) (api-response :type +api-error-unknown+ :content "Invalid parameter"))))

I've also started using validate in Podcastinet, with a similar macro that sends back a 400 error in the event validation fails. Right now, there isn't a good way to collect failed validations for a meaningful error for the API consumer, but I suppose that will come in time.

In any event, it was a fun project and made me feel pretty good about nest, since I was able to use it to build an app in an afternoon. Now I need to make a docker image so I can throw it up on a server and keep track of my groceries! Check out the project here and let me know what you think. I'd also really appreciate feedback on validate. Maybe I'll post it to the lisp subreddit, soon, for some of that.