I'm following the official racket example for URL-based dispatch, but can't seem to get it to work correctly.
#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)
When I run the .rkt file, the web server seems to work correctly. But when I actually hit the main page (http://localhost:8080/ or whatever) I get a generic "Welcome to Racket" page instead of the response I specified in the dispatch rules. If I hit localhost:8080/posts/test, I get an error that the page I specified is missing. Am I missing something obvious here?
There are a few problems with your code, though not all of them are really your fault. The web-server
API is kinda weird, and the serve/servlet
API especially so.
First of all, you should not use #lang web-server/insta
if you want to use the serve/servlet
API directly. Use #lang web-server
instead if you want to use stateless servlets, or use #lang racket
or #lang racket/base
for stateful ones. As your code is currently written, it will use the start
function as the entry point for web-server/insta
as well as the invokation of serve/servlet
, so you’re effectively launching a web server twice.
Second of all, the way serve/servlet
works is a little confusing: by default, it only captures requests at the path that you specify with #:servlet-path
. I find that this is usually not what I want, so you want to provide #:servlet-regexp #rx""
to allow the servlet to handle requests to any path.
Finally, your servlet functions themselves do not return valid responses. You probably want to return some kind of JSON or HTML. You need to construct a response struct and return that, but you can use helper functions like response/xexpr
to do that pretty easily.
With all those changes, your code should look something like this:
#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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With