Welcome to Racket Stories.
Racket Stories is a place where you can find and share links to anything Racket related: blog posts, tutorials, new packages, papers etc.
Racket Stories is at the same time a show case for a "production" web-site written in Racket with the source being available at Github. There are many ways to write web-apps, so the source is just an example of one way to use Racket.
If you find bugs, large or small, submit an issue at Github
Have fun with it.
Jens Axel Søgaard
jensaxel@soegaard.net
The main reason for publishing the source is that I want people to have something to try and tinker with, without inventing anything from scratch. All you need to try the web-site on your own machine is to clone the Github repo, install a few packages, and run the code. No configuration is needed.
The source code for this application is available at Github.:
Here are the packages you need besides the packages that are included in the standard Racket distribution.
raco pkg install deta
raco pkg install urlang
raco pkg install threading
The app uses the Model-View-Controller architecture (MVC).
To make this super clear the app consists of the files model.rkt, view.rkt and control.rkt. In a larger application it would make sense to make separate folders for the model, view and control — and split the files into smaller pieces. For example each html page in view.rkt could get its own file.
The model (see model.rkt) consists of a database in which the the urls and scores are stored. You can open model.rkt in your editor, run it and then experiment in the repl with (top 3), (page 1) etc.
The view (see view.rkt) presents data from the model to the user. In the case of an web-app the view generates html which is sent to the user's browser.
The control (see control.rkt) accepts input from the user, reads or writes to the model, and then sends output back using the view to present the output
The server (see server.rkt) takes care of receiving requests from the users and sending back responses. For this application the server will send all requests to the control to be handled.
Some of the packages the app relies on are listed below.
The Deta library is used to map database tables to Racket structs. After updating the values of a struct, Deta can send the relevant changes to the database. In fact Deta can be used to perform Create-Read-Update-Delete (CRUD) operations on your model — as well as making arbitrary queries.
You can think of Deta as an Object-Relational Mapper using structs instead of objects.
The db library is the foundation for Deta. We are also using it to create the initial database connection. Using db has the effect that we can easily switch between PostgreSQL, SQLite and MySQL backends.
A popular approach of representing html is S-expression. In this app we have however chosen to represent html as structures. This choice has a few advantages: First of all we can use Scribble's at-expressions to construct html. Second, calling functions that constructs pieces of html looks the same as a call that constructs an actual html construct.
A wrapper of scribble/html that provides a few utilities that makes it easier to work with the element structure of scribble/html. One of the provided functions is ~x which converts an element into string.
The threading library provides a few macros that flatten nested function calls. Here we/Deta use ~> to construct database queries with a nice syntax.
The web-server library provides tools for working with requests and responses. It also makes it easy to get a server up and running without a lengthy installation and configuration process.