racket/collects/web-server/scribblings/web.scrbl
Jay McCarthy e1dab52b07 compat
svn: r13922
2009-03-03 20:02:31 +00:00

207 lines
6.9 KiB
Racket

#lang scribble/doc
@(require "web-server.ss")
@title[#:tag "web.ss"]{Web Interaction}
@(require (for-label web-server/servlet/web
web-server/servlet/servlet-structs
web-server/http
net/url))
@defmodule[web-server/servlet/web]{The
@schememodname[web-server/servlet/web] library provides the primary
functions of interest for the servlet developer.
@defproc[(send/back [response response/c])
void?]{
Sends @scheme[response] to the client. No continuation is captured, so the servlet is done.
Example:
@schemeblock[
(send/back
`(html
(body
(h1 "The sum is: "
,(+ first-number
second-number)))))
]
}
@defproc[(send/suspend [make-response (string? . -> . response/c)])
request?]{
Captures the current continuation, stores it with @scheme[exp] as the expiration
handler, and binds it to a URL. @scheme[make-response] is called with this URL and
is expected to generate a @scheme[response/c], which is sent to the client. If the
continuation URL is invoked, the captured continuation is invoked and the request is
returned from this call to @scheme[send/suspend].
Example:
@schemeblock[
(send/suspend
(lambda (k-url)
`(html (head (title "Enter a number"))
(body
(form ([action ,k-url])
"Enter a number: "
(input ([name "number"]))
(input ([type "submit"])))))))
]
When this form is submitted by the browser, the request will be sent to the URL generated by @scheme[send/suspend].
Thus, the request will be ``returned'' from @scheme[send/suspend] to the continuation of this call.
}
@defproc[(send/suspend/url [make-response (url? . -> . response/c)])
request?]{
Like @scheme[send/suspend] but with a URL struct.
}
@defproc[(send/suspend/dispatch [make-response (((request? . -> . any) . -> . string?) . -> . response/c)])
any]{
Calls @scheme[make-response] with a function (@scheme[embed/url]) that, when called with a procedure from
@scheme[request?] to @scheme[any/c] will generate a URL, that when invoked will call
the function with the @scheme[request?] object and return the result to the caller of
@scheme[send/suspend/dispatch]. Therefore, if you pass @scheme[embed/url] the identity function,
@scheme[send/suspend/dispatch] devolves into @scheme[send/suspend]:
@schemeblock[
(define (send/suspend response-generator)
(send/suspend/dispatch
(lambda (embed/url)
(response-generator (embed/url (lambda (x) x))))))
]
Use @scheme[send/suspend/dispatch] when there are multiple `logical' continuations of a page.
For example, we could either add to a number or subtract from it:
@schemeblock[
(define (count-dot-com i)
(count-dot-com
(send/suspend/dispatch
(lambda (embed/url)
`(html
(head (title "Count!"))
(body
(h2 (a ([href
,(embed/url
(lambda (req)
(sub1 i)))])
"-"))
(h1 ,(number->string i))
(h2 (a ([href
,(embed/url
(lambda (req)
(add1 i)))])
"+"))))))))
]
Notice that in this example the result of the handlers are returned to the continuation of @scheme[send/suspend/dispatch].
However, it is very common that the return value of @scheme[send/suspend/dispatch] is irrevelant in
your application and you may think of it as ``embedding'' value-less callbacks. Here is the same example in this style:
@schemeblock[
(define (count-dot-com i)
(send/suspend/dispatch
(lambda (embed/url)
`(html
(head (title "Count!"))
(body
(h2 (a ([href
,(embed/url
(lambda (req)
(count-dot-com (sub1 i))))])
"-"))
(h1 ,(number->string i))
(h2 (a ([href
,(embed/url
(lambda (req)
(count-dot-com (add1 i))))])
"+")))))))
]
}
@defproc[(send/suspend/url/dispatch [make-response (((request? . -> . any) . -> . url?) . -> . response/c)])
any]{
Like @scheme[send/suspend/dispatch], but with a URL struct.
}
@defproc[(send/forward [make-response (string? . -> . response/c)])
request?]{
Calls @scheme[clear-continuation-table!], then @scheme[send/suspend].
Use this if the user can logically go `forward' in your application, but cannot go backward.
}
@defproc[(send/finish [response response/c])
void?]{
Calls @scheme[clear-continuation-table!], then @scheme[send/back].
Use this if the user is truly `done' with your application. For example, it may be used to display the post-logout page:
@schemeblock[
(send/finish
`(html (head (title "Logged out"))
(body (p "Thank you for using the services "
"of the Add Two Numbers, Inc."))))
]
}
@defproc[(redirect/get)
request?]{
Calls @scheme[send/suspend] with @scheme[redirect-to].
This implements the Post-Redirect-Get pattern.
Use this to prevent the @onscreen["Refresh"] button from duplicating effects, such as adding items to a database.
}
@defproc[(redirect/get/forget)
request?]{
Calls @scheme[send/forward] with @scheme[redirect-to].
}
@defthing[current-servlet-continuation-expiration-handler (parameter/c expiration-handler/c)]{
Holds the @scheme[expiration-handler/c] to be used when a continuation
captured in this context is expired, then looked up.
Example:
@schemeblock[
(parameterize
([current-servlet-continuation-expiration-handler
(lambda (req)
`(html (head (title "Custom Expiration!"))))])
(send/suspend
....))
]
}
@defproc[(clear-continuation-table!)
void?]{
Calls the servlet's manager's @scheme[clear-continuation-table!] function. Normally, this deletes all the previously
captured continuations.
}
@defproc[(with-errors-to-browser [send/finish-or-back (response/c . -> . request?)]
[thunk (-> any)])
any]{
Calls @scheme[thunk] with an exception handler that generates an HTML error page
and calls @scheme[send/finish-or-back].
Example:
@schemeblock[
(with-errors-to-browser
send/back
(lambda ()
(/ 1 (get-number (request-number)))))
]
}
@defproc[(adjust-timeout! [t number?])
void?]{
Calls the servlet's manager's @scheme[adjust-timeout!] function.
@warning{This is deprecated and will be removed in a future release.}
}
@defproc[(continuation-url? [u url?])
(or/c false/c (list/c number? number? number?))]{
Checks if @scheme[u] is a URL that refers to a continuation, if so
returns the instance id, continuation id, and nonce.
}
}