Racket URL Dispatch Rules

use*_*559 4 lisp scheme racket

我正在关注基于URL的调度的官方球拍示例,但似乎无法让它正常工作.

#lang web-server/insta  
(require web-server/servlet
         web-server/servlet-env)

(define (start request)
  (blog-dispatch request))

(define-values (blog-dispatch blog-url)
  (dispatch-rules
   (("") list-posts)
   (("posts" (string-arg)) review-post)
   (else list-posts)))

(define (list-posts req) `(list-posts))
(define (review-post req p) `(review-post ,p))

(serve/servlet start
               #:servlet-path ""
               #:port 8080)
Run Code Online (Sandbox Code Playgroud)

当我运行.rkt文件时,Web服务器似乎正常工作.但是当我实际访问主页面时(http:// localhost:8080 /或其他)我得到了一个通用的"欢迎使用Racket"页面,而不是我在调度规则中指定的响应.如果我点击localhost:8080/posts/test,我收到的错误是我指定的页面丢失了.我错过了一些明显的东西吗?

Ale*_*ing 7

您的代码存在一些问题,但并非所有问题都是您的错.该web-serverAPI是有点怪异,和serve/servletAPI尤其如此.

首先,你应该使用#lang web-server/insta,如果你想使用serve/servlet直接API.使用#lang web-server,如果你想使用无状态的servlet或使用替代#lang racket#lang racket/base有状态的.由于您的代码当前已编写,因此它将使用该start函数作为入口点web-server/insta以及调用serve/servlet,因此您可以有效地启动Web服务器两次.

其次,serve/servlet工作方式有点令人困惑:默认情况下,它只捕获您指定的路径上的请求#:servlet-path.我发现这通常不是我想要的,所以你想提供#:servlet-regexp #rx""允许servlet处理对任何路径的请求.

最后,您的servlet函数本身不会返回有效的响应.您可能想要返回某种JSON或HTML.你需要构造一个响应结构并返回它,但是你可以使用辅助函数response/xexpr来做到这一点非常容易.

通过所有这些更改,您的代码应如下所示:

#lang racket/base

(require web-server/servlet
         web-server/servlet-env)

(define (start request)
  (blog-dispatch request))

(define-values (blog-dispatch blog-url)
  (dispatch-rules
   (("") list-posts)
   (("posts" (string-arg)) review-post)
   (else list-posts)))

(define (list-posts req)
  (response/xexpr `(html (body "list-posts"))))
(define (review-post req p)
  (response/xexpr `(html (body (div "review-post: " ,p)))))

(serve/servlet start
               #:servlet-path "/"
               #:servlet-regexp #rx""
               #:port 8080)
Run Code Online (Sandbox Code Playgroud)