On this page:
top
up

5URL-Based DispatchπŸ”— i

The library allows the creation of two-way mappings between permanent URLs and request-handling procedures.

This library was inspired by the (planet untyped/dispatch) package.

5.1Using web-server/dispatch πŸ”— i

Suppose you are writing a blog application and want pretty URLs for different views of the site. You would define some URL dispatching rules as follows:

> (define-values (blog-dispatchblog-url)
[("")list-posts]
[("posts"(string-arg ))review-post]
[("archive"(integer-arg )(integer-arg ))review-archive]
[else list-posts]))

And define your request handlers as follows:
> (define (list-postsreq)`(list-posts))
> (define (review-postreqp)`(review-post,p))
> (define (review-archivereqym)`(review-archive,y,m))

Now when a request is sent to your application, it will be directed to the appropriate handler:
> (define (url->requestu)
(delayempty )#f"1.2.3.4"80"4.3.2.1"))
> (blog-dispatch
(url->request"http://www.chrlsnchrg.com"))

'(list-posts)

> (blog-dispatch
(url->request"http://www.chrlsnchrg.com/"))

'(list-posts)

> (blog-dispatch
(url->request
"http://www.chrlsnchrg.com/posts/Extracurricular-Activity"))

'(review-post "Extracurricular-Activity")

> (blog-dispatch
(url->request"http://www.chrlsnchrg.com/archive/1984/10"))

'(review-archive 1984 10)

> (blog-dispatch
(url->request"http://www.chrlsnchrg.com/contact"))

'(list-posts)

You can also generate these pretty URLs from procedure calls:
> (blog-urllist-posts)

"/"

> (blog-urlreview-post"Another-Saturday-Night")

"/posts/Another-Saturday-Night"

> (blog-urlreview-archive198411)

"/archive/1984/11"

After mastering the world of blogging software, you decide to put the ubiquitous Add-Two-Numbers.com out of business with Sum.com:
> (define-values (sum-dispatchsum-url)
[((integer-arg )... )sum]
[else (lambda (req)(sumreqempty ))]))
> (define (sumreqis)
(apply + is))
> (sum-dispatch(url->request"http://www.sum.com/"))

0

> (sum-dispatch(url->request"http://www.sum.com/2"))

2

> (sum-dispatch(url->request"http://www.sum.com/2/3/4"))

9

> (sum-dispatch(url->request"http://www.sum.com/5/10/15/20"))

50

> (sum-urlsumempty )

"/"

> (sum-urlsum(list 1))

"/1"

> (sum-urlsum(list 2357))

"/2/3/5/7"

When you use web-server/dispatch with serve/servlet , you almost always want to use the #:servlet-regexp argument with the value "" to capture all top-level requests. However, make sure you don’t include an else in your rules if you are also serving static files, or else the filesystem server will never see the requests.

5.2API ReferenceπŸ”— i

syntax

dispatch-clause...
maybe-else-clause)
dispatch-clause = [dispatch-patternmaybe-methoddispatch-fun]
dispatch-pattern = ()
| (string. dispatch-pattern)
| (bidi-match-expander.... dispatch-pattern)
| (bidi-match-expander. dispatch-pattern)
maybe-method =
| #:methodmethod
method = pat
maybe-else-clause =
| [else else-fun]
else-fun : (request? . -> .any )
dispatch-fun : (request? any/c ... . -> .any )
Returns two values: the first is a dispatching function with the contract (-> request? any ) that calls the appropriate dispatch-fun based on the first dispatch-pattern that matches the request’s URL (and method), the second is a URL-generating function with the contract (-> procedure? any/c ... string? ) that generates a URL using dispatch-pattern for the dispatch-fun given as its first argument.

If else-fun is left out, one is provided that calls (next-dispatcher ) to signal to the Web Server that this dispatcher does not apply.

The method syntax is used in a match expression to match the request-method part of the incoming request object. However, since HTTP allows methods to use any case, the byte string from request-method is normalized to a lower-case string. Thus, valid patterns are things like: "get", "post", "head", (or "get""post"), etc.

If method is left out, it assumed to apply to requests without methods and GET methods.

syntax

dispatch-clause...
maybe-else-clause)
Like dispatch-rules , except returns a third value with the contract (-> request? boolean? ) that returns #t if the dispatching rules apply to the request and #f otherwise.

syntax

dispatch-clause...
maybe-else-clause)
Returns a dispatching function as described by dispatch-rules .

syntax

[dispatch-patterndispatch-fun]
...)
dispatch-fun : (request? any/c ... . -> .any )
Returns a URL-generating function as described by dispatch-rules .

procedure

( serve/dispatch dispatch)void

dispatch:(request? . -> .can-be-response? )
Calls serve/servlet with a #:servlet-regexp argument (#rx"") so that every request is handled by dispatch.

5.3Imperative Dispatch ContainersπŸ”— i

dispatch-rules is purely functional. This presents a more declarative interface, but inhibits some programming and modularity patterns. Containers provide an imperative overlay atop dispatch-rules .

procedure

( container? x)boolean?

x:any/c
Identifies containers.

syntax

( define-container container-id(dispatch-idurl-id))

Defines container-id as a container as well as dispatch-id as its dispatching function and url-id as its URL lookup function.

syntax

( dispatch-rules! container-expr[dispatch-patterndispatch-fun]...)

Like dispatch-rules , but imperatively adds the patterns to the container specified by container-expr. The new rules are consulted before any rules already in the container.

5.4Built-in URL patternsπŸ”— i

web-server/dispatch builds in a few useful URL component patterns.

syntax

( number-arg )

A bi-directional match expander that parses a number? from the URL and generates a URL with a number’s encoding as a string.

syntax

( integer-arg )

A bi-directional match expander that parses a integer? from the URL and generates a URL with a integer’s encoding as a string.

syntax

( real-arg )

A bi-directional match expander that parses a real? from the URL and generates a URL with a real’s encoding as a string.

syntax

( string-arg )

A bi-directional match expander that parses a string? from the URL and generates a URL containing the string.

syntax

( symbol-arg )

A bi-directional match expander that parses a symbol? from the URL and generates a URL with a symbol’s encoding as a string.

5.5Extending web-server/dispatch πŸ”— i

package: web-server-lib

You can create new URL component patterns by defining bi-directional match expanders.

syntax

( define-bidi-match-expander idin-xformout-xform)

Binds id to a bi-directional match expander where in-xform is a match expander (defined by define-match-expander ) that is used when parsing URLs and out-xform is one used when generating URLs.

Both in-xform and out-xform should use the syntax (xformarg... id) where the args are specific to id and compatible with both in-xform and out-xform. id will typically be provided automatically by dispatch-rules .

A syntax parameter used by bi-directional match expanders to determine if a URL is being parsed or generated.

When defining new patterns, you may find it useful to use these helper functions:

syntax

( define-coercion-match-expander idtest?coerce)

Binds id to a match expander that expands (idx) to (?test?(appcoercex)) (i.e., uses test? to determine if the pattern matches and coerce to transform the binding.)

procedure

( make-coerce-safe? coerce)(any/c . -> .boolean? )

coerce:(any/c . -> .any/c )
Returns a function that returns #t if coerce would not throw an exception or return #f on its input.

Examples:
> (define string->number?(make-coerce-safe? string->number ))
> (string->number?"1")

#t

> (string->number?"1.2")

#t

> (string->number?"+inf.0")

#t

> (string->number?"one")

#f

top
up

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /