Next: , Up: snooze   [Contents][Index]


2.15.1 Example of a micro-REST Service

This establishes two routes (‘GET’ for reading and ‘POST’ for writing) on the URI localhost:9003/lispdoc/<symbol>.

(defpackage #:readme-demo (:use #:cl #:snooze))
(in-package #:readme-demo)

(defun find-symbol-or-lose (name package)
  (or (find-symbol (string name) (find-package package))
      (http-condition 404 "Sorry, no such symbol")))

(defroute lispdoc (:get :text/* name &key (package :cl) (doctype 'function))
  (or (documentation (find-symbol-or-lose name package) doctype)
      (http-condition 404 "Sorry, ~a doesn't have any ~a doc" name doctype)))

(defroute lispdoc (:post :text/plain name &key (package :cl) (doctype 'function))
  (setf (documentation (find-symbol-or-lose name package) doctype)
        (payload-as-string)))

;; Let's use clack as a server backend
(clack:clackup (snooze:make-clack-app) :port 9003)

Here’s an illustration of how they respond:

GET /lispdoc/defun                         => 200 OK
GET /lispdoc/funny-syntax?package=snooze   => 404 Not found
GET /lispdoc/in/?valid=args                => 400 Bad Request

GET /lispdoc/defun                         => 406 Not Acceptable
Accept: application/json

POST /lispdoc/scan?package=cl-ppcre        => 200 OK
Content-type: text/plain

POST /lispdoc/defun                        => 415 Unsupported Media Type
Content-type: application/json

The error codes 400, 406 and 415 are error reporting that you get "for free": if the HTTP client strays off these routes, be it for improper syntax or unsupported content types, the correct HTTP condition is signalled.

There are already some Common Lisp systems for HTTP routing, like

Unfortunately, they tend to make you learn some extra route-defining syntax.

On the contrary Snooze maps REST/HTTP concepts to Common Lisp concepts:

HTTP-REST ConceptSnooze CL Concept
REST ResourceCLOS generic function
RouteCLOS method
Verbs (GET, POST, DELETE, etc)CLOS specializer on first argument
Accept: and Content-Type:CLOS specializer on second argument
URI path (/path1/path2/path3))Required and optional arguments
URL queries (?param=value&p2=v2)Keyword arguments
Status codes (404, 500, etc)CL conditions

This has many advantages, for example:


Next: Tutorial, Up: snooze   [Contents][Index]