This codebase aims to be an example for a full stack websocket-driven reflex project of sufficient complexity. By sufficient, I mean that this should provide a better idea of how to start building a real-world application, of greater complexity than, say, a "Hello World" demonstration.
First, read the reflex project document (it's not long). A great starting point after reading that document would be ElvishJerricco's reflex-project-skeleton, which is what this codebase started from.
- Add iOS app
- Add bin/ scripts for android, ios, backend, etc.
- Perhaps capture slides of some backend / common code
- Show new frontend app code
- Try adding a new feature, such as editing text
- Add active user count
- Add note about Requester typeclass and a GADT api (or just figure it out)
- Development scripts in bin, for those of us less familiar with nix.
- Complete configuration of Android and iOS apps, and scripts for deploying them.
- Slides from presenting this application (coming soon).
To build the project to its various compilation targets, see bin/build --help
. For example,
# build frontend web app
./bin/build frontend
ls dist-frontend/index.html
# build android app
./bin/build android
ls dist-android/android-app.apk
# build ios ad-hoc app
# TODO this will have more arguments
./bin/build --ad-hoc ios
ls dist-ios/ios-app.ipa
# deploy ios app to connected device
./bin/build ios
To develop on top of this project, or a fork off it:
# get those sweet ghcid shells, for whichever parts of the codebase you are working on
./bin/ghcid frontend
./bin/ghcid backend
./bin/ghcid test
# start up the backend
./bin/ghci backend # main
# start up a warp frontend
./bin/ghci frontend # warp
# code & reload ghci modules as necessary
Some things will obviously change when trying to build an app that really scales. I remembered reading about acid-state in the 24 Days of Hackage article so I chose to try that out here, and it fits the bill very well for this todo list. However, most people will probably reach for a more familiar database such as postgres. If postgres were being used here, there wouldn't be too much of a code change, but one thing would be cleaned up: broadcasting.
At work, we have an architecture using reflex, websockets, and postgres, and we leverage postgres NOTIFY/LISTEN so that whenever updates are made to the database we can parse the notification and propagate the new state directly to all the frontend clients. This way, each websocket connection doesn't need to worry about communicating with all the other connections, but we still maintain a very high level of interactivity.