Response

Best Practice

To simplify debugging, it is better to use structured logging and include a request id into all log messages and HTTP server response.

Adding such request id is as simple as adding a method for reblocks/request-handler:handle-request generic-function:

(defmethod reblocks/request-handler:handle-request ((app app))
  (let ((*request-id* (make-request-id)))
    (reblocks/response:add-header :x-request-id
                                  *request-id*)
    (with-fields (:request-id *request-id*)
      (call-next-method))))

Here we use log4cl-extras/context:with-fields macro for structured logging and reblocks/response:add-header to add the X-Request-Id header to webserver's response.

Also, you might want to define a method for reblocks/error-handler:on-error generic-function and show current request-id to the user. This way he could provide id to support simplifying issue investigation.

API

Use this function to add a HTTP header:

(add-header :x-request-id "100500")
function
uri &key (retpath (get-uri))

Adds a "retpath" GET parameter to the giving URL.

Keeps all other parameters and overwrites "retpath" parameter if it is already exists in the URL.

By default, retpath is the current page, rendered by the reblocks. This is very useful to redirect user to login page and return him to the same page where he has been before.

function
&optional (response \*response\*)

Returns a status code to be returned in response to the current request.

You can use SETF to change the status code:

(setf (reblocks/response:status-code)
      404)
function
&optional (response \*response\*)
function
&optional (response \*response\*)
function
&optional (response \*response\*)
function
cookie &key (response \*response\*)

Use this function to add Set-Cookie header:

(set-cookie (list :name "user_id" :value "bob" :samesite :lax))

Cookie might include these properties:

  • domain

  • path

  • expires

  • secure

  • httponly

  • samesite

function
&optional (response \*response\*)

Returns a list with a map cookie-name -> cookie:cookie object. Odd items in this list are cookie names and even are lists with cookie parameters.

function
content &key (condition-class 'immediate-response) (code 200) content-type headers cookies-to-set

Aborts request processing by signaling an immediate-response and returns a given value as response.

HTTP code and headers are taken from CODE and CONTENT-TYPE.

By default, headers and cookies are taken from the current request, but additional headers and cookies may be provides in appropriate arguments.

function
content &key (code 200) (content-type (get-default-content-type-for-response)) (headers (get-headers))

Makes a new URL, based on the current request's URL.

Argument NEW-PATH can be absolute, like /logout or relative, like ./stories.

Also, it can contain a query params like /login?code=100500

By default, function takes a base-uri from the current request, bun in case if you want to call the function in a context where request is not available, you can pass BASE-URI argument explicitly.

function
script &optional (place :after-load)

Send JavaScript to the browser. The way of sending depends on whether the current request is via AJAX or not.

Script may be either a string or a list; if it is a list it will be compiled through Parenscript first.

Deprecated

function
&optional (response \*response\*)

Function get-code is deprecated. Use status-code instead.

function
&optional (response \*response\*)

Function get-custom-headers is deprecated. Use get-headers instead.